TWebbrowser大量内存泄漏:目前没有解决方案。

4
我有一个应用程序,使用 TWebbrowser 定期导航到特定的 URL 并提取一些数据。该应用程序持续运行 24x7 并在页面中进行了大量导航。
问题在于,TWebbrowser 存在众所周知的内存泄漏问题,每次导航到新页面时,应用程序使用的内存都会增加。我的应用程序可以轻松地在一段时间后使用超过 2GB 的 RAM。并且在导航了数百次之后,会抛出 'Out of memory''Out of system resources' 异常,唯一解决方法是重新启动应用程序。
奇怪的是,FASTMM 从未显示这些泄漏。当我使用我的应用程序几分钟并关闭它时,没有任何报告。
我已经寻找了多年的解决方案(实际上自从我编写应用程序的第一个版本以来就一直如此)。有一些变通方法,但事实上,它们都没有解决问题。对我来说,唯一的解决方法是定期关闭和打开应用程序。
我已经测试了 SetProcessWorkingSetSize 方法,但它只是暂时缩小了应用程序使用的内存。几秒钟后,应用程序又使用了大量的内存。
我也尝试过 EmbeddedWB,但由于它是从 TWebbrowser 派生的,所以它受到相同问题的困扰。
顺便说一下,我不能使用像 IdHTTP 这样的简单组件,因为我需要在访问的网站中执行一些 JavaScript 操作。
有人知道是否真的有解决这个问题的方法吗?

2
你真的不应该使用可视化组件来进行非可视化工作。寻找另一种解决方案。至于 FastMM,它并没有分配 WebBrowser 内部内存,因此无法跟踪它。 - Remy Lebeau
有一些解决方案的线索,但这取决于您的要求。例如,(1)您能否每小时关闭浏览器?(2)必须是MSIE吗?顺便说一句,“开始悬赏”确实是回答这样一个问题的公平方式。 - stanleyxu2005
可能是 https://dev59.com/U2LVa4cB1Zd3GeqP0eCf 的重复问题。 - Josh Kelley
1个回答

7

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


我已经进行了修复并且能够重现修复的过程,但是组件在使用过程中仍然会越来越多地占用内存... - delphirules
1
@delphirules - 我最终调试TWebBrowser内存泄漏的方法是使用TTimer事件,多次调用泄漏代码(这样我可以轻松地看到是否发生了泄漏),然后重复删除或注释掉代码块并重新运行,直到我能够确定哪些代码行触发了泄漏。希望这可以帮助你。 - Josh Kelley
6
如果你的泄漏问题是由QC#106829引起的,那么请使用browser.DefaultInterface.Document代替browser.Document。如果您的泄漏问题是由其他原因引起的,请确定在代码中导致泄漏的过程或表单,使用TTimer事件多次调用它(以便泄漏非常明显),然后开始删除或注释掉您的过程或表单中的代码块,直到您确定导致泄漏的特定语句。 - Josh Kelley
1
@delphirules - 根据我们所做的测试,我们能够处理快速刷新的JavaScript重页面,而不消耗大量内存。另一方面,我们只需要处理一些特定的页面和站点,你使用TWebBrowser可能与我们不同。无论如何,我已经看到足够多的人使用TWebBrowser和TEmbeddedWB的评论,我相信它可以被制作出来。 - Josh Kelley
1
原来在10.0 Seattle版本中修复了TOleControl.GetIDispatchProp/GetIUnknownProp()的错误。 - Remy Lebeau
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接