Delphi TWebBrowser内存泄漏

时间:2012-04-19 09:00:03

标签: delphi delphi-2009 twebbrowser

我的应用程序使用加载网页的TWebBrowser。问题是,在关闭包含TWebBrowser的表单后,使用的内存不会被释放。如果我打开并关闭表单,内存会不断增加。

看到一些关于调用SetProcessWorkingSetSize()或CoFreeUnusedLibrariesEx()的帖子来解决这个问题,但我不确定这些是否是正确的解决方案。

知道如何释放TWebBrowser使用的内存吗?

6 个答案:

答案 0 :(得分:3)

QC#106829描述了使用TWebBrowser导致内存泄漏的一个可能原因。访问Document(以及通过TOleControl.GetIDispatchPropTOleControl.GetIUnknownProp实现的任何其他属性)会导致泄漏,因为它在不调用Release的情况下调用AddRef。作为解决方法,您可以手动调用Release,也可以修补VCL(see here),或者可以避免有问题的属性(例如,使用browser.DefaultInterface.Document代替browser.Document

答案 1 :(得分:1)

使用TWebBrowser在幕后做了很多工作,很多相同的工作都是Internet Explorer的完整实例。它对你来说是隐藏的,但它仍然存在,并且很有可能我们无法强行从记忆中移除它。检查页面加载之前和之间的内存使用情况,并测试调用Navigate('about:blank');时发生的情况。还要检查你的析构函数是否被正确调用,并考虑从OnClose或OnCloseQuery调用Navigate('about:blank');。我发现这确实有助于记忆情况。

答案 2 :(得分:0)

最好的解决方案是使用TWebbrowser停止。

CEF4Delphi是一个使用Chrome而不是Internet Explorer的免费库。始终保持最新且非常高效:

https://github.com/salvadordf/CEF4Delphi

答案 3 :(得分:-1)

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}

要清除内存,我使用此功能,在论坛的某个地方找到。它比SetProcessWorkingSetSize()方法更好地清除“工作集”,但它更难调用并且它在Winapi.PsAPI单元中注册。 但是,我注意到这两个函数都清理了“工作集”。如果查看任务管理器中的“已分配内存”列,则可以看到此参数未被清除。清理后我的应用程序的“工作集”可以减少到10 MB,但所有分配的内存将保持等于1.5 GB。并且,在我看来,这是导致错误“内存不足”的原因。如果你长时间看重型网站,这个错误仍会出现。

答案 4 :(得分:-2)

要释放内存,只需初始化新文档:

(WebBrowser.Document as IPersistStreamInit).InitNew;

答案 5 :(得分:-2)

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

并不时给它打电话

FreeMemory;