4

使用 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

4 回答 4

3

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

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

于 2011-05-18T22:10:12.767 回答
0

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

于 2011-05-18T22:16:09.110 回答
0

你试过 Navigate('about:blank'); 在释放之前?这应该已经释放了一些内存。我还认为 WebBrower 的内部结构(与 Internet Explorer 的内部结构大致相同)在内存中保留了很多东西,只是为了将历史记录和缓存提供给可能存在的任何其他 TWebBrowser(或者更具体的 IWebBrowser2)这个会话的可执行文件,甚至在(不远的)将来。

运气好的话(如果您使用的是 Navigate 或 Navigate2),如果您使用navNoHistory、navNoWriteToCache等标志调用,则可以更改此设置。

于 2011-05-19T17:25:03.330 回答
0

这个问题困扰了 TWebbrowser 用户多年,至今没有解决方案;释放 TWebbrowser 使用的内存的唯一方法是关闭您的应用程序并再次打开它。

于 2015-06-11T01:33:06.890 回答