如何释放IHTMLDocument使用的内存?

时间:2011-05-18 21:49:36

标签: delphi winapi memory com twebbrowser

有没有办法在使用IHTMLDocument(IHTMLDocument2)后释放内存?

目前我正在使用EmptyWorkingSet功能,但我觉得这不是一个好方法

EmptyWorkingSet(GetCurrentProcess);

即使释放TWebBrowser也无济于事;问题似乎是在IHTMLDocument COM类中,它没有从内存中释放出来。是否有明确的方式来释放它;类似于Marshal.ReleaseComObject但可用于Delphi的东西?

与运行JavaScript相比,它可以重现,内存丢失更少,但仍然如此。如果您在表单顶部放置两个按钮并尝试以下代码...

uses MSHTML, SHDocVw;

type
  TForm1 = class(TForm)
  private
    WebBrowser: TWebBrowser;
    HTMLDocument: IHTMLDocument2;
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  WebBrowser := TWebBrowser.Create(nil);
  TWinControl(WebBrowser).Parent := Self;
  WebBrowser.SetBounds(8, 39, ClientWidth-16, ClientHeight-47);
  WebBrowser.Navigate('http://maps.google.com/');
  HTMLDocument := WebBrowser.Document as IHTMLDocument2;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  WebBrowser.Free;
  HTMLDocument := nil;
end;

每次WebBrowser释放后,您将看到内存丢失。当我运行我的JavaSrcipt时,它甚至超过300 kB,大约1 MB,这可能会导致内存泄漏,以防我多次运行。

非常感谢

4 个答案:

答案 0 :(得分:3)

当您释放对它们的所有引用时,通常应释放COM类。通常,这可以通过将nil分配给保存对其接口的引用的所有变量来完成。

要立即释放COM DLL使用的内存,您可以使用CoFreeUnusedLibrariesEx

答案 1 :(得分:0)

我不知道Delphi,但我在C ++中使用过IHTMLDocument。我相信你需要调用Release()方法。我也知道它对字符串使用BSTR,因此可能是寻找未被释放的内存的另一个地方。

答案 2 :(得分:0)

您是否尝试过Navigate('about:blank');在释放之前?这应该已经释放了一些记忆。我也认为来自WebBrower的内部(与Internet Explorer大致相同的内部构件)在内存中保留了很多东西,只是为了提供历史记录并缓存到任何其他TWebBrowser(或IWebBrowser2)更具体的)可能存在于此可执行文件的会话中,即使在(近)未来也是如此。

运气好(如果您使用的是Navigate或Navigate2),如果您使用flags like navNoHistory, navNoWriteToCache和其他人进行通话,则可以更改此内容。

答案 3 :(得分:0)

这个问题困扰着TWebbrowser用户多年,到目前为止还没有解决方案;释放TWebbrowser使用的内存的唯一方法是关闭你的应用程序并再次打开它。