Форум: "Основная";
Текущий архив: 2006.11.12;
Скачать: [xml.tar.bz2];
ВнизПроблема с утечкой памяти (использую MemProof) Найти похожие ветки
← →
JohnnyRaw (2006-09-20 18:01) [0]Ситуация такая:
При каждом последуещем запуске процедуры, количество используемой приложением памяти увеличивается (при слежении в windows task manager: немного в "+", немного в "-", но в целом стабильно растет), потом, через n-количество выполнения этой процедуры, приложение начинает очень сильно тормозить...
Опыт с memproof показал след. результаты:
после троекратного выполнения процедуры и выхода из программы лог такой
386 Live Pointer 03881F54 28
387 Critical Section 03881F58 0 InitializeCriticalSection
17551 Error 000001E7 0 VirtualAlloc(03980000,1048576,8192,4) : Attempt to access invalid addr
17552 Error 000001E7 0 VirtualAlloc(03980000,65536,8192,4) : Attempt to access invalid addres
26016 Error 000001E7 0 VirtualAlloc(048C0000,1048576,8192,4) : Attempt to access invalid addr
26017 Error 000001E7 0 VirtualAlloc(048C0000,65536,8192,4) : Attempt to access invalid addres
38791 SysString 055F004C 140564 SysAllocStringLen(,140564)
107491 SysString 06C3F3FC 140564 SysAllocStringLen(,140564)
175529 SysString 06C3FFC4 140564 SysAllocStringLen(,140564)
подозрение вызывают особенно 3 последние строчки, но ума не приложу откуда ноги растут.
в процедуре создаю следующее:
Log:=TStringList.Create;
cfProg:=TIniFile.Create("C:\...\Delphi7\Projects\config.ini");
v:=VarArrayCreate([0,0], VarVariant);
List:=TStringList.Create;
Idoc:=CreateComObject(Class_HTMLDOcument) as IHTMLDocument2;
m: Array of Array of String;
память от них освобождаю так:
IDoc:=nil;
VarClear(v);
cfProg.Free;
Finalize(m);
FreeAndNil(Log);
FreeAndNil(List);
заранее спасибо за любое участие
← →
Правильный Вася (2006-09-20 19:00) [1]If the interface returned by CreateCOMObject is assigned to a Variant, you can release the interface by assigning the Unassigned constant to that Variant.
IDoc:=nil;
ку?
← →
JohnnyRaw (2006-09-20 20:30) [2]не, чето не ку (
IDoc: IHTMLDocument2;
← →
Правильный Вася (2006-09-20 21:07) [3]> m: Array of Array of String;
а вложенные очичаешь?
← →
JohnnyRaw (2006-09-20 21:07) [4]вот конкретный пример кода:
uses
.....
ComObj, ActiveX;
procedure hiddenleak;
var
IDoc: IHTMLDocument2;
v: Variant;
MarHTML: String;
begin
HTML:=Form1.IdHttp1.Get("http://localhost/01.html");
Idoc:=CreateComObject(Class_HTMLDOcument) as IHTMLDocument2;
v:=VarArrayCreate([0,0], VarVariant);
v[0]:= MarHTML;
IDoc.write(PSafeArray(System.TVarData(v).VArray));
IDoc:=nil;
VarClear(v);
end;
выполняется с десяток циклов - плюс еще мегабайт памяти, как освобождать - absolutely no idea
← →
guav © (2006-09-20 21:29) [5]
> IDoc:=nil;
Это не надо, оно и само делается.
> VarClear(v);
Это тоже.
> Finalize(m);
А это вообще лучше убрать.
Может в этом и ошибка, если для явного Finalize генерируется не-вложенная финализация.
← →
JohnnyRaw (2006-09-20 21:48) [6]все убрал осталось лишь:
begin
HTML:=Form1.IdHttp1.Get("http://localhost/01.html");
Idoc:=CreateComObject(Class_HTMLDOcument) as IHTMLDocument2;
v:=VarArrayCreate([0,0], VarVariant);
v[0]:= MarHTML;
IDoc.write(PSafeArray(System.TVarData(v).VArray));
end;
результат нулевой
после десятикратного выполнения процедуры лог от memproof такой:
404 Live Pointer 02412090 28
00000069 C:\Program Files\Borland\Delphi7\Projects\Project1.exe
00403C6E C:\Program Files\Borland\Delphi7\Projects\Project1.exe
7C816D4A RegisterWaitForInputIdle C:\WINDOWS\system32\kernel32.dll
405 Critical Section 02412094 0 InitializeCriticalSection
0042B20B C:\Program Files\Borland\Delphi7\Projects\Project1.exe
00403C6E C:\Program Files\Borland\Delphi7\Projects\Project1.exe
7C816D4A RegisterWaitForInputIdle C:\WINDOWS\system32\kernel32.dll
2379 SysString 001DDA54 140564 SysAllocStringLen(,140564)
4051 SysString 044A2704 140564 SysAllocStringLen(,140564)
7801 SysString 0445DCBC 140564 SysAllocStringLen(,140564)
9598 SysString 045B56A4 140564 SysAllocStringLen(,140564)
11248 SysString 045FA05C 140564 SysAllocStringLen(,140564)
12844 SysString 045FA05C 140564 SysAllocStringLen(,140564)
14409 SysString 051E004C 140564 SysAllocStringLen(,140564)
15961 SysString 05225A14 140564 SysAllocStringLen(,140564)
17476 SysString 0526A43C 140564 SysAllocStringLen(,140564)
19052 SysString 0526A43C 140564 SysAllocStringLen(,140564)
это что по ~140 K за один цикл утекает?
где-то такие же результаты дает наблюдение за TaskManager"ом
← →
guav © (2006-09-20 21:59) [7]> System.TVarData(v).VArray
VarArrayAsPSafeArray ?
← →
evvcom © (2006-09-21 08:15) [8]> [4] JohnnyRaw (20.09.06 21:07)
> var
> MarHTML: String;
> begin
> HTML:=...
> v[0]:= MarHTML;
Что это за HTML? И тогда MarHTML остается пустой строкой.
> Idoc:=CreateComObject(..)
очищается, наверное, так же как и при CreateOleObject, причем лучше в защищенном блоке это делать:
Idoc:=CreateComObject(..);
try
// Здесь прочая лабуда, где возможны исключительные ситуации
finally
Idoc := Unassigned;
end;
← →
JohnnyRaw (2006-09-21 11:39) [9]> [4] JohnnyRaw (20.09.06 21:07)
> var
> MarHTML: String;
> begin
> HTML:=...
> v[0]:= MarHTML;
это просто опечатка, строки одинаковые
> Idoc := Unassigned;
IDoc: IHTMLDocument2 а не вариант, ему нельзя присвоить Unassigned
Блин да что же это такое (( нашел несколько примеров в инете, почитал книгу Delphi и технология COM, нигде про дополнительное освобождение памяти не говориться, только Idoc := Nil;
Возникает вопрос: то ли лыжи не едут, то ли......
если кому не трудно посмотрите как у вас работает этот код
procedure leak;
var
IDoc: IHTMLDocument2;
v: Variant;
HTML: String;
begin
HTML:=Form1.IdHttp1.Get("http://localhost/01.html");
Idoc:=CreateComObject(Class_HTMLDOcument) as IHTMLDocument2;
try
v:=VarArrayCreate([0,0], VarVariant);
v[0]:= HTML;
IDoc.write(PSafeArray(System.TVarData(v).VArray));
Finally
IDoc:=Nil;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
leak;
Button1Click(Form1);
end;
у меня за пять минут работы кол-во используемой приложением памяти возрастает вдвое
← →
atruhin © (2006-09-21 12:02) [10]Попробуй FastMM, он помимо всего прочего, при утечке памяти показывает строку в которой эта память была распределена, для какого класса, стек вызова и т.д.
← →
Romkin © (2006-09-21 15:22) [11]Млиин!!!
var
V: OleVariant;
HtmlDoc: IHTMLDocument2;
begin
WB.Navigate("about:blank"); //чтобы документ был
OleCheck(WB.Document.QueryInterface(IHTMLDocument2, HtmlDoc));
V := VarArrayCreate([0, 0], varVariant);
V[0] := ppText.Content;
//и просто пишем в пустой документ...
//Как ни странно, VArray & PSafeArray - одно и то же :)
HtmlDoc.write(PSafeArray(TVarData(V).VArray));
HtmlDoc.close;
SetRightAnswerText; //К делу не относится
end;
← →
JohnnyRaw (2006-09-21 23:40) [12]
> Млиин!!!
> var
> V: OleVariant;
> HtmlDoc: IHTMLDocument2;
> begin
...
..
есть конечно и такой вариант, но имхо не очень красивый, т.к. надо размещать TWebBrowser на форме, и как его адаптировать к работе в дополнительном потоке?
Провел такой эксперимент сделал две схожие процедуры одна с CreateComObject другая c WebBrowser, и запустил каждую в цикле от 0 до 999 по очереди.
в первом варианте (с COM) последний цикл выполнялся 3.9 сек, программа занимала в памяти 44636К
во втором варианте последний цикл выполнялся уже 4.8 сек, но программа занимала в памяти 17636К
т.ч. вопрос открыт, почему возникают такие тормоза при выполнении простейших процедур, куда девается память и как ее вернуть?
вот эти процедуры:procedure leak1;
var
V: OleVariant;
HtmlDoc: IHTMLDocument2;
HTML: String;
begin
HTML:=Form1.IdHttp1.Get("http://localhost/01.html");
Form1.WB.Silent:=True;
Form1.WB.Visible:=False;
Form1.WB.Navigate("about:blank");
//зачем OleCheck?
OleCheck(Form1.WB.Document.QueryInterface(IHTMLDocument2, HtmlDoc));
HtmlDoc := Form1.WB.Document as IHtmlDocument2;
V := VarArrayCreate([0, 0], varVariant);
V[0] := HTML;
HtmlDoc.Write(PSafeArray(TVarData(v).VArray));
HtmlDoc.Close;
end;procedure Leak2;
var
IDoc: IHTMLDocument2;
v: Variant;
HTML: String;
begin
HTML:=Form1.IdHttp1.Get("http://localhost/01.html");
IDoc:=CreateComObject(Class_HTMLDOcument) as IHTMLDocument2;
v:=VarArrayCreate([0,0],VarVariant);
v[0]:= HTML;
IDoc.write(PSafeArray(System.TVarData(v).VArray));
IDoc:=nil;
end;
← →
KOTuK (2006-09-29 18:50) [13]А ты подожди секунд 10-30 ПОСЛЕ выполнения кода, т.е. не закрывай форму, понаблюдай результат в memproof....
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.11.12;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.033 c