窗口关闭事件不释放内存和资源。如何解决WPF中的内存泄漏问题?

时间:2012-05-29 17:28:21

标签: wpf memory-leaks

最近我注意到我的WPF项目中存在严重的内存泄漏。如果简化项目,它有一个登录表单和一个主表单。在主窗体中有1个用户控件,它由大约30个用户控件和3个按钮组成,1个用户控件有3个按钮和一个Infragistics数据网格。我使用后台工作程序每隔30秒仅为数据网格查询数据库。

在使用main form.closed注销主窗体并重新启动登录窗口后,我注意到每次ANTS内存分析器7测量增加了6-7MB。即使我有未注册的事件处理程序,设置变量为null并调用GC.Collect(),记忆泄漏仍然是一样的。我的问题是: 1.为什么关闭wpf窗口不释放内存和资源?我可以看到许多字符串(大多数来自GUI)在ANTs分析器关闭窗口后仍然在内存中。 2.我是否需要取消注册资源事件设置器定义的事件?我是否需要取消注册XAML中声明的事件? 3.从WPF memory leak,人们说我们不应该使用GC.Collect(),但我确实看到了一些改进。我们要不要使用它?

3 个答案:

答案 0 :(得分:2)

使用WindowsFormsHost进行PictureBox控件时遇到了类似的问题。 使用WF PictureBox控件的WPF窗口无法完全释放,这就是为什么每次重新打开子窗口时我都会增加~10mb的常规值。 问题解决了,因为我开始在WPF窗口关闭时取消WFH对象。 如果你使用它,请确保清除所有WF控件。

答案 1 :(得分:0)

进入调试器,然后在立即窗口中输入:

.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll

sos.dll的路径各不相同。找出正确路径的方法是在“模块”窗格中查找mscorwks.dll。无论从哪里加载的是sos.dll的正确路径。

然后输入:

System.GC.Collect()

这将确保收集任何无法到达的内容。然后输入:

!DumpHeap -type <some-type-name>

这将显示包含地址的所有现有实例的表。您可以找到保持实例活着的内容:

!gcroot <some-address>

最初由Daniel

回答

答案 2 :(得分:0)

这取决于。 WPF中的用户控件本身并不处理,因此您必须覆盖功能并在控件中允许它:

http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx

但是就你的观点而言,你需要至少进行一次GC.Collect(),如SlimGG建议的那样。

在大多数情况下,直接调用垃圾收集器被认为是不好的做法,因为它没有专门为您的控件调用它,而是排队等待处理的所有对象。