这是 .NET Webbrowser 控件的一个广为人知的老问题。
总结:让 .NET webbrowser 控件导航到页面会增加从未释放的内存使用量。
重现内存泄漏:将 WebBrowser 控件添加到窗体。使用它导航到您想要的任何页面。 about:blank 有效,在 Google 图片上向下滚动直到您的使用量超过 100MB,然后浏览其他地方以发现几乎没有任何内存被释放,这是一个更具戏剧性的演示。
我目前对应用程序的要求包括长时间运行它,显示有限的 IE7 浏览器窗口。运行 IE7 本身并带有一些 SCSS 设置的钩子(Hook)、BHO 和组策略也是不希望的,尽管此时这看起来像是回退。 将浏览器嵌入到 Windows 窗体应用程序中。 使用不同的浏览器基础对我来说不是一个可用的选项。 IE7 是必需的。
与此已知内存泄漏相关的先前线程和文章:
- http://www.vbforums.com/showthread.php?t=644658
- How to Fix the Memory Leak in IE WebBrowser Control?
- Memory leak when using WPF WebBrowser control in multiple windows
- http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/88c21427-e765-46e8-833d-6021ef79e0c8/
- http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/8a2efea4-5e75-4e3d-856f-b09a4e215ede
- http://dotnetforum.net/topic/17400-appdomain-webbrowser-memory-leak/
经常提出的不起作用的修复:
- 转到不同的页面并不重要。 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/