.net - 如何解决 .NET Webbrowser 控件中的内存泄漏问题?

标签 .net memory memory-leaks browser webbrowser-control

这是 .NET Webbrowser 控件的一个广为人知的老问题。

总结:让 .NET webbrowser 控件导航到页面会增加从未释放的内存使用量。

重现内存泄漏:将 WebBrowser 控件添加到窗体。使用它导航到您想要的任何页面。 about:blank 有效,在 Google 图片上向下滚动直到您的使用量超过 100MB,然后浏览其他地方以发现几乎没有任何内存被释放,这是一个更具戏剧性的演示。

我目前对应用程序的要求包括长时间运行它,显示有限的 IE7 浏览器窗口。运行 IE7 本身并带有一些 SCSS 设置的钩子(Hook)、BHO 和组策略也是不希望的,尽管此时这看起来像是回退。 将浏览器嵌入到 Windows 窗体应用程序中。 使用不同的浏览器基础对我来说不是一个可用的选项。 IE7 是必需的。

与此已知内存泄漏相关的先前线程和文章:

经常提出的不起作用的修复:

  • 转到不同的页面并不重要。 about:blank 触发泄漏。它不需要页面具有 javascript 或任何其他额外技术。
  • 使用不同版本的 Internet Explorer 并不重要。 7、8 和 9 都表现出相同的症状,据我所知,所有版本的控件都有相同的内存泄漏。
  • Dispose()ing 控件没有帮助。
  • 垃圾收集没有帮助。 (事实上​​,我对此进行的研究表明,泄漏发生在 Webbrowswer 控件包装的非托管 COM 代码中。)
  • 最小化进程可用内存并将其设置为 -1、-1(SetProcessWorkingSetSize() 或类似。)只会减少物理内存使用量,对虚拟内存没有影响。
  • 调用 WebBrowser.Stop() 不是解决方案,它破坏了使用静态网页以外的任何东西的功能,而不仅仅是稍微减少泄漏。
  • 在导航到另一个文档之前强制等待文档完全加载也无济于事。
  • 在单独的 appDomain 中加载控件并不能解决问题。 (我自己没有这样做,但研究表明其他人在这条路线上没有成功。)
  • 使用不同的包装器(例如 csexwb2)并没有帮助,因为这也会遇到同样的问题。
  • 清除 Internet 临时文件缓存没有任何作用。问题出在事件内存中,而不是在磁盘上。

当整个应用程序关闭并重新启动时,内存被清除。

我愿意直接在 COM 或 Windows API 中编写我自己的浏览器控件,如果这是对问题的肯定解决方案的话。当然,我更喜欢不太复杂的修复;我宁愿避免下降到较低的级别来做事,因为我不想在浏览器支持的功能方面重新发明轮子。更不用说在自己滚动的浏览器中复制 IE7 功能和非标准行为了。

帮助?

最佳答案

此泄漏似乎是非托管内存中的泄漏,因此您在进程中所做的任何事情都不会回收该内存。从您的帖子中,我可以看到您已经尝试非常广泛地避免泄漏,但没有成功。

如果可行,我会建议一种不同的方法。创建一个使用 Web 浏览器控件的单独应用程序并从您的应用程序启动它。使用描述的方法here将新创建的应用程序嵌入到您自己现有的应用程序中。使用 WCF 或 .NET 远程处理与该应用程序通信。不时重新启动子进程以防止它占用太多内存。

这当然是一个相当复杂的解决方案,重启过程可能看起来很难看。每次用户导航到另一个页面时,您可能会求助于重新启动整个浏览器应用程序。

关于.net - 如何解决 .NET Webbrowser 控件中的内存泄漏问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8302933/

相关文章:

java - 引用匿名类构造函数中的最终对象泄漏?

angular - 如何正确使用OnDestroy

.net - 正确支持 WPF 的混淆器

c# - VB.NET 代码片段是否可用于 C#?

c++ - 额外字节在 C++ 中是否初始化为 0?

Python 似乎在完成对这些十六进制值的循环之前就要死了。怎么修?

c++ - vector 内存泄漏

c# - 使用 .NET 即时生成 visio 图

c# - 你如何使用 log4.net 编写 byte[] 数组

ios - renderInContext 对应用程序内存征税