0

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

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

4

3 回答 3

2

在将 WindowsFormsHost 用于 PictureBox 控件时,我遇到了一个类似的问题。使用 WF PictureBox 控件的 WPF 窗口无法完全释放,这就是为什么我每次重新打开子窗口时都会定期增加 ~10mb。自从我在 WPF 窗口关闭时开始清空 WFH 对象后,问题就解决了。如果您使用此类,请确保您清除所有 WF 控件。

于 2012-10-16T22:50:25.147 回答
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>

最初由丹尼尔回答

于 2012-05-29T17:35:50.937 回答
0

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

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

但就您而言,您需要按照 SlimGG 的建议至少执行一次 GC.Collect() 。

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

于 2012-05-29T22:08:05.550 回答