【问题标题】:window closed event doesn't release memory and resource. How to solve the memory leak in WPF?窗口关闭事件不会释放内存和资源。如何解决 WPF 中的内存泄漏?
【发布时间】:2012-06-03 22:57:32
【问题描述】:

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

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

【问题讨论】:

    标签: wpf memory-leaks


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

      • 我发现 1 个地方由于使用 DependencyPropertyDescriptor.FromProperty...AddValueChanged 但未删除更改的值而导致代码中的内存泄漏。但是,我仍然注意到其他窗口中的内存泄漏。我同意我们调用 GC.Collect 因为用户控件内部有用户控件。谢谢。
      【解决方案3】:

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

      .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回答

      【讨论】:

        猜你喜欢
        • 2013-09-20
        • 1970-01-01
        • 2013-01-02
        • 2011-08-26
        • 2017-04-24
        • 1970-01-01
        • 2012-06-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多