Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
5-1142771273
Кашперук Иван
2006-03-19 15:27
2006.11.12
Real-Time отрисовка Caption


2-1161775849
KyRo
2006-10-25 15:30
2006.11.12
Код Enter


2-1161736729
Lex_!
2006-10-25 04:38
2006.11.12
Поля в ДБГриде


2-1161942939
term1t
2006-10-27 13:55
2006.11.12
statement too long


1-1159538518
_Guest_
2006-09-29 18:01
2006.11.12
загрузка dll-ки





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский