Delphi TWebBrowser Memory Leak

断了今生、忘了曾经 提交于 2019-12-13 12:12:22

问题


My application uses a TWebBrowser that loads a webpage. The problem is, after closing the form containing the TWebBrowser, the memory used is not freed. If I open and close the form, the memory just keeps on increasing.

Saw some post regarding calling SetProcessWorkingSetSize() or CoFreeUnusedLibrariesEx() to solve this issue, but I'm not sure if any of these are the correct solution.

Any idea how to free the memory used by TWebBrowser?


回答1:


QC#106829 describes one possible cause of memory leaks with TWebBrowser. Accessing Document (and any other properties that are implemented via TOleControl.GetIDispatchProp or TOleControl.GetIUnknownProp) causes leaks because it calls AddRef without ever calling Release. As a workaround, you can manually call Release, or you can patch the VCL (see here), or you can avoid the problematic properties (for example, by using browser.DefaultInterface.Document instead of browser.Document).




回答2:


Using TWebBrowser does a lot of work behind the scenes, much of the same work a full instance of Internet Explorer would do. It is hidden from you, but still it's there and chances are it's unaccessible for us to force removing from memory. Check the memory usage before and between page loads, and test what happens when you call Navigate('about:blank');. Also check whether your destructor gets called properly, and consider calling Navigate('about:blank'); from OnClose or OnCloseQuery. I found this does help the memory-situation a little bit.




回答3:


The best solution is STOP using TWebbrowser.

CEF4Delphi is a free library that uses Chrome instead of Internet Explorer. Always up to date and very efficient :

https://github.com/salvadordf/CEF4Delphi




回答4:


Uses Winapi.PsAPI;
 ...
{$IFDEF WIN32}
procedure TForm1.MemoryFree;
var
  HandleCaptureProcessus: THandle;
  UnProcessus: TProcessEntry32;
  PIDProcessus: THandle;
  HandleProcessus: THandle;
  NameOfProcess: string;
begin
  PIDProcessus := 4294967295;
  NameOfProcess := ExtractFileName(Application.ExeName);

  HandleCaptureProcessus := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  UnProcessus.dwSize := SizeOf(TProcessEntry32);

  Process32First(HandleCaptureProcessus, UnProcessus);
  repeat
    if UnProcessus.szExeFile = NameOfProcess then
    begin
      PIDProcessus := UnProcessus.th32ProcessID;
      Break;
    end;
  until not Process32Next(HandleCaptureProcessus, UnProcessus);

  if PIDProcessus = 4294967295 then
  begin
    CloseHandle(HandleCaptureProcessus);
    exit;
  end;

  HandleProcessus := OpenProcess(PROCESS_ALL_ACCESS, False, PIDProcessus);

  EmptyWorkingSet(HandleProcessus);

  CloseHandle(HandleProcessus);
end;
{$ELSE}
procedure TForm1.MemoryFree;
begin
  //**
end;
{$ENDIF}

To clear the memory, I use this function, found somewhere on the forums. It clears the "Working Set" much better than the SetProcessWorkingSetSize () method, but it is more difficult to call and it is registered in the Winapi.PsAPI unit. But, I noticed that both of these functions clean the "Working Set". And if you look at the "Allocated memory" column in the Task Manager, you can see that this parameter is not cleared. The "working set" of my application after cleaning can be reduced to 10 MB, but the all allocated memory will remain equal to 1.5 GB. And, in my opinion, this is what causes the error "Out of memory". And this error still appears if you look at heavy websites for a long time.




回答5:


To free up the memory, just initialize the new document:

(WebBrowser.Document as IPersistStreamInit).InitNew;



回答6:


procedure TForm1.FreeMemory;
begin
    if Win32Platform = VER_PLATFORM_WIN32_NT then
    SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
end;

and call it from time to time

FreeMemory;


来源:https://stackoverflow.com/questions/10224801/delphi-twebbrowser-memory-leak

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!