Текущий архив: 2002.04.18;
Скачать: CL | DM;
Вниз
Люди!!! Ткните мне, пожалуйста, пальцем в утечку памяти. Найти похожие ветки
← →
khodov (2002-04-06 21:28) [0]Я сделал упрощенный пример, который моделирует мою проблему. Вот две процедуры, которые реагируют на кнопки на форме.
Как Вы легко поймете, первая, с каждым новым кликом, создает массив строк, которым присваивает различную длину.
Вторая должна почистить память.
Но в результате, если нажимать по такой схеме:
12
112
1112
11112
и т.д., т.е. 1-ю кнопку нажимать все больше раз, то происходит все большая утечка памяти примерно по 4-8 Kb.
Расскажите, пожалуйста в чем дело?!?!?!?
type
ptry1=^ttry1;
ttry1=array[1..4096] of string;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
t : array of ptry1;
{ Public declarations }
end;
procedure TForm1.Button1Click(Sender: TObject);
var
p : ptry1;
i : longint;
s : String;
begin
new(p);
for i:=1 to 4096 do
Begin
setlength(s,i);
p^[i] := s;
setlength(s,0);
End;
i := length(t);
setlength(t, i+1);
t[i] := p;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i,j: longint;
begin
for i := 0 to length(t)-1 do
Begin
for j := 1 to 4096 do
setlength(t[i]^[j],0);
dispose(t[i]);
End;
t:=nil;
end;
← →
MBo (2002-04-06 21:39) [1]Код довольно экзотический. Что он должен делать?
← →
khodov (2002-04-06 22:10) [2]Да там реальный код сложнее. Этот - просто макет, который производит ту же утечку, что и реальная прога.
Ну, я знаю, что если в первой процедуре на использовать s, а сразу устанавливать длину для элементов массива, то утечки нету. Так в чем проблема? кто знает?
← →
Anatoly Podgoretsky (2002-04-06 22:14) [3]Do not apply the dereference operator (^) to a dynamic-array variable or pass it to the New or Dispose procedure.
Это из хелпа
← →
MBo (2002-04-06 22:17) [4]По-видимому, так -
при расширении дин.массива или строки выделяется новый кусок памяти, а в старый уже не запишешь, т.к. он мал. Вот и накапливается пустое место мелкими порциями
← →
khodov (2002-04-06 22:20) [5]To Anatoly Podgoretsky:
Если Вы говорите про строку:
dispose(t[i]);
то я использую dispose не с dynamic-array variable, а с Pointer-ом типа ptry1, что считаю вполне корректным.
Ошибкой было бы использование dispose(t)
Или я ошибаюсь?
← →
khodov (2002-04-06 22:24) [6]To Mbo:
А не можете ли Вы чего-нибудь посоветовать. У меня в реальной проге расход памяти доходит до 200Mb в результате этого.
← →
MBo (2002-04-06 22:32) [7]А TStringList не подойдет?
← →
Anatoly Podgoretsky (2002-04-06 22:35) [8]khodov © (06.04.02 22:20)
Извиняюсь, не обратил внимания
← →
khodov (2002-04-06 22:39) [9]Не-е. Дело в том, что там не просто строки, а записи, в которых есть строки, указатели на объекты, и т.д. Но проблема возникает только со строками. Я просто не стал делать записи со строками, а сделал статический массив.
← →
MBo (2002-04-06 22:52) [10]в этой процедуре выделяется примерно 8 мег памяти
for i:=1 to 4096 do
Begin
setlength(s,i);
p^[i] := s;
setlength(s,0);
End;
← →
Fantasist (2002-04-07 02:21) [11]Хе-хе. Здорово!
Вот тут Делфи над вами со своей удобной(!) строкой и издевается. :)
Для начала - строка в Делфи - это указатель. Но компилятор все за вас делает так, что вам кажеться что это обыкновенная переменная.
Теперь, возми и вначале процедуры:
procedure TForm1.Button1Click(Sender: TObject);
сделай sizeof(p^). Сделай это и в конце этой процедуры, и сравни размеры. Они одинаковые! А куда же делась память, которую ты выделил для каждой строки? Ага, вот то-то и оно. Твой:
ttry1=array[1..4096] of string; - это массив указателей, и когда ты радостно грохаешь его в своем dispose, то освобождается ровно 4*4096 байт. А все строки остаются висеть в памяти. Не круто ли. :)
← →
khodov (2002-04-07 07:55) [12]To MBo:
Я знаю, что 8 мег выделяется.
To Fanatist:
Спасибо за вводный курс лекций :). Я имею дело с Delphi начиная с 1-й версии и даже раньше :). За это время я успел изучить изменения, произошедшие со строками. Если ты не заметил, то перед тем, как освободить массив, я очищаю память, занятую каждой строкой в массиве.
Кроме того, если присмотрется внимательно к дискуссии, то можно заметить, что я совершенно точно указываю место, где спрятана проблема. Она в первой процедуре.
Люди!!! Не спрашивайте, пожалуйста, что за странный код!!! Это просто макет демонстрирующий проблему. Я не могу выкинуть сюда 150Kb исходников и попросить Вас разобраться.
Если кто-то знает, что добавить в первую процедуру или всю прогу, чтобы память из-под S освобождалась корректно, помогите пожалуйста!!
← →
Fantasist (2002-04-07 09:17) [13]2khodov:
:)
Опс... Облом. А так хотелось кого-то поучить. Без наездов. :)
> Если ты не заметил, то перед тем, как освободить массив,
> я очищаю память, занятую каждой строкой в массиве.
Заметил. А потом забыл.
Попробую посмотреть по внимательнее.
А все-таки, а не пробывал ли ты то же самое сделать через PChar?
Страницы: 1 вся ветка
Текущий архив: 2002.04.18;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.008 c