Форум: "Основная";
Текущий архив: 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
ща поглядииииим...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.04.08;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c