Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.08;
Скачать: [xml.tar.bz2];




Вниз

Сборщик мусора в памяти ? 


Dimedrol   (2002-03-27 13:55) [0]

Коллеги, у меня подозрение, что я в своей программе где-то не освобождаю память... ;-(
1. Не знает ли кто какие-нить методы диагностики МЕСТА
утечки памяти ?

2. А нет ли каких-нить библиотек для сабжа ?
То бишь они например на OnIdle вешаются и освобождают память,
на которую например никто не ссылается, ну и в таком же духе... а?!

Я гоняю кусок моей проги долго-долго и смотрю в Таск Манагер.
(под Вин2000)
так память в нем НЕ уменьшается, а наоборот немного
увеличивается - скачкообразно через несколько десятков итераций...

Что делать ?



Alx2   (2002-03-27 14:05) [1]

По поводу занятой памяти: попробуй повесить это на таймер, а Edit1 - на видное место :)
Потом погоняй проблемное место. IMHO, методом последовательный приближений можно найти.

Function haircut(Const S: String): String;
Var K, L: Integer;
Begin
Result := "";
L := 1;
For K := Length(S) Downto 1 Do
Begin
Result := S[K] + Result;
If L Mod 3 = 0 Then Result := " " + Result;
Inc(L);
End;
End;

Var K: Integer;
MemInfo: TMemoryStatus;
Begin
MemInfo.dwLength := Sizeof(MemInfo);
GlobalMemoryStatus(MemInfo);
Edit1.Text := "Занято:" +haircut(IntToStr(AllocMemSize)) +
" (" + haircut(IntToStr(MemInfo.dwAvailPageFile Div 1024)) + "Kb) ";
End;



vuk   (2002-03-27 14:08) [2]

http://www.automatedqa.com/downloads/memproof.asp



Dimedrol   (2002-03-27 14:12) [3]

2 Alx2 - Спасибо, ща погоняю...


В коде я населяю TreeView на основании
массива поинтеров, указывающх на record
с разными значениями конечно...


А вообще вот проблемный код :
-----------------------------

procedure TMacForm.AddChildToGroup(m:word);
var i,j:word;
Vals,SecList:TStringList;
sBuf,select:string;
CNode:TTreeNode;
TmpMac:PMacro;
begin

try
try
//New(TmpMac);
//GetMem(TmpMac, SizeOf(TmpMac));

И вне цикла создавал...

for i:=0 to ScTree.Items.Count-1 do
begin
if ScTree.Items[i].Data<>nil then
begin
GetMem(TmpMac, SizeOf(TmpMac));

И внутри тоже - 1 хрен ! ;-(

TmpMac:=ScTree.Items[i].Data;
if TmpMac^.id=MacList[m]^.parid then

^^^^^^^^^^^^^^^^^
ВО! тут самое главное.
Мне этот поинтер-то нужен
просто 2 значения полей сравнить...



begin
CNode:=ScTree.Items.AddChild(ScTree.Items[i], ShortCutToText(MacList[m]^.HotKey));
CNode.ImageIndex:=1;
CNode.SelectedIndex:=1;
CNode.Data:=MacList[m];
//Dispose(TmpMac);
FreeMem(TmpMac, SizeOf(TmpMac));
exit;
end;
FreeMem(TmpMac, SizeOf(TmpMac));
//Dispose(TmpMac);

Тут пытался освободить...


end;
end;

except
on E:Exception do
begin
MessageDlg("App returned error: "+#10+#13+E.Message,mtWarning,[mbOK],0);
exit;

Как пытаюсь освободить - 1 раз проходит !!!
а потом вот тут все время вываливаюсь... ;-(

end;
end;

finally
//Dispose(TmpMac);
//FreeMem(TmpMac, SizeOf(TmpMac));

И тут тоже - пофигу...


end;
end;



PVOzerski   (2002-03-27 14:13) [4]

Помнится, на "Базарной площади" "Королевства Delphi" этот вопрос обсуждался:
http://www.delphikingdom.com/cgi-bin/talk.cgi?ID=183
Насколько помню, пришли к невозможности решения проблемы в общем виде. Но полезные мысли там
есть, и немало. От себя добавлю: один из моих "любимых" источников утечки памяти - взаимодействие
GetMem/FreeMem/ReallocMem с длинными строками. Суть в том, что если создавать и убирать через
эти функции массивы или записи, содержащие длинные строки, то, в отличие от New/Dispose, при
высвобождении памяти не проверяется ассоциированность полей-длинных строк с блоками памяти,
динамически выделенными при присвоении им значений и, соответственно, эти блоки "повисают"
неосвобождёнными . Может, эта мысль Вам пригодится.



Dimedrol   (2002-03-27 14:16) [5]

2 vuk -
Спасибо, качаю... посмотрим...



vuk   (2002-03-27 14:19) [6]

to PVOzersky:
Специально для этих случаев есть стандартная процедура Finalize.



Dimedrol   (2002-03-27 14:20) [7]

2 PVOzerski

вообще-то в таких "проблемных" местах я ваще стараюсь со
строками неопределенной длины не работать (фу! ;-)
вот тип данных для моих поинтеров

type

PMacro = ^TMacro;
TMacro = record
id: integer;
parid: integer;
isgroup:byte; //1-yes,255-no
GrpName:string[32];
Rubric:string[2];
lang:byte; //0-RU, 1-LV
HotKey: TShortCut;
text: shortstring;
end;

var
MacList: array[1..2048] of PMacro;

А потом работаю с массивом поинтеров


procedure TMacForm.NewMacList;
var i:word;
begin
for i:=1 to 2048 do
begin
try New(MacList[i]); except end;
//MacList[i]^:=nil; нужно ли это ???
end;
end;


procedure TMacForm.ResetMacList;
var i:word;
begin
for i:=1 to 2048 do
begin
//MacList[i]^:=nil; нужно ли ???
try Dispose(MacList[i]); except end;
try New(MacList[i]); except end;

типа ресет... ;-) а может НИЛ делать ?

end;
end;

procedure TMacForm.FreeMacList;
var i:word;
begin
for i:=1 to 2048 do
begin
//MacList[i]^:=nil; ???
try Dispose(MacList[i]); except end;
end;
end;


Вот такие пироги...



oomneeq   (2002-03-27 14:24) [8]

Простая и эффективная примочка для поиска
Всего то один юнит,
подключаешь к проекту, вызываешь один раз одну процедурку в самом начале dpr
и по закрытию программы получаешь список всех неосвобожденных участков с указанием номеров строк исходника где это случилось

http://v.mahon.free.fr/pro/freeware/memcheck/

Транслируешь с нужными опциями (см. фак там же)



Dimedrol   (2002-03-27 14:42) [9]

2 oomneeq
ща поглядииииим...




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.08;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.75 MB
Время: 0.02 c
3-22576           Zloy                  2002-03-18 07:03  2002.04.08  
Приветствую!!! Подскажите плиз, как сделать так чтобы таблица после каждого заполнения или редактирования какого-то поля 100% сохраналась


1-22719           vlv                   2002-03-26 20:45  2002.04.08  
Как очистить TBitmap?


3-22561           der                   2002-03-12 05:09  2002.04.08  
Нумерация ячеек в DBGRID


3-22577           Вика                  2002-03-15 13:06  2002.04.08  
Автофильтр в Excel


1-22664           Сатир                 2002-03-28 11:34  2002.04.08  
Отображение элементов списка TList