【发布时间】:2011-08-28 10:18:57
【问题描述】:
使用 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,如果我运行这么多次,这可能会导致内存泄漏。
非常感谢
【问题讨论】:
-
EmptyWorkingSet实际上并没有释放任何内存。它只是将活动内存分页到磁盘。您的进程仍然拥有该内存;访问它会将其分页回 RAM。您如何衡量您的进程的内存消耗,以及是什么让您认为您有问题需要解决? -
顺序可能重要吗?尝试首先将
nil分配给HTMLDocument,然后然后释放WebBrowser。另一个(可能不相关)的事情是,WebBrowser.Document可能在Navigate之后立即没有有效的IHtmlDocument2(页面可能仍在加载)。您可能应该使用像OnDocumentComplete这样的事件。 -
只是一个想法:甚至可以在释放之前尝试
Navigate('about:blank')。 -
还有一个想法:我记得在进程外 COM 类中遇到过类似问题,CoFreeUnusedLibrariesEx 解决了它。
-
谢谢,很高兴能帮上忙! :-)
标签: delphi winapi memory com twebbrowser