如何释放IHTMLDocument使用的内存?
使用 IHTMLDocument (IHTMLDocument2) 后有没有办法释放内存?
目前我正在使用 EmptyWorkingSet 函数但我觉得这不是一个好方法
EmptyWorkingSet(GetCurrentProcess);
即使释放 TWebBrowser 也没有帮助;问题似乎出在 IHTMLDocument COM 类中,该类未从内存中释放。有没有明确的释放方式;类似于 Marshal.ReleaseComObject 但可用对于德尔福?
与运行 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,如果我运行这么多次,这可能会导致内存泄漏。
多谢
is there a way to release memory after using IHTMLDocument (IHTMLDocument2) ?
Currently I'm using EmptyWorkingSet function but I feel that it's not a good way to do it
EmptyWorkingSet(GetCurrentProcess);
Even freeing the TWebBrowser doesn't help; the problem seems to be in IHTMLDocument COM class which is not released from the memory. Is there a clear way to release it; something like Marshal.ReleaseComObject but available for Delphi ?
It's reproducable with less memory lose than with running JavaScript, but still. If you put two buttons on the top of the form and try the following code ...
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;
You will see the memory lose after each WebBrowser freeing. When I run my JavaSrcipt it's much even more than 300 kB, it's about 1 MB and this may cause a memory leak in case I'm running this many times.
Thanks a lot
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您释放对 COM 类的所有引用时,通常应该释放 COM 类。通常,这可以通过将 nil 分配给所有持有其接口引用的变量来完成。
要立即释放 COM DLL 使用的内存,您可以使用 CoFreeUnusedLibrariesEx。
The COM classes should normally be freed when you release all references to them. Usually this can be done by assigning nil to all variables holding references to their interfaces.
For immediate release of memory used by COM DLLs you can use CoFreeUnusedLibrariesEx.
我不知道 Delphi,但我用过 C++ 中的 IHTMLDocument。我相信您需要调用 Release() 方法。我还知道它使用 BSTR 作为字符串,因此这可能是另一个地方查找未释放的内存。
I don't know Delphi but I've worked with IHTMLDocument in C++. I believe you need to call the Release() method. I also know it uses BSTR for strings so that might be another place to look for memory not being released.
您是否尝试过 Navigate('about:blank');释放之前?这应该已经释放了一些内存。我还认为 WebBrower 的内部结构(与 Internet Explorer 的内部结构大致相同)在内存中保存了很多内容,只是为了将历史记录和缓存提供给任何其他 TWebBrowser(或 IWebBrowser2)更具体地说)可能存在于可执行文件的此会话中,即使在(不久的)将来也是如此。
运气好的话(如果您使用的是 Navigate 或 Navigate2),如果使用 诸如 navNoHistory、navNoWriteToCache 等标志。
Have you tried Navigate('about:blank'); before freeing? This should already free some memory. I also think the internals from WebBrower (which are roughly the same internals as Internet Explorer), keep a lot of things in memory, just to serve the history and cache to any other TWebBrowser (or IWebBrowser2 to be more specific) that may exist in this session of the executable, even in the (near) future.
With a bit of luck (and if you are using Navigate or Navigate2), you could change this if you call with flags like navNoHistory, navNoWriteToCache and perhaps others.
这个问题困扰了TWebbrowser用户多年,至今没有解决方案;释放 TWebbrowser 使用的内存的唯一方法是关闭您的应用程序并再次打开它。
This problem is plaguing TWebbrowser users for ages and there is no solution so far ; the only way to release the memory used by TWebbrowser is to close your app and open it again.