【问题标题】:Windows Forms application memory leak .NETWindows 窗体应用程序内存泄漏 .NET
【发布时间】:2013-06-19 11:22:40
【问题描述】:

有一个 winforms 应用程序,其中几个表单非常复杂 - 使用数据集、与网格和组合框的多个绑定.. 每次打开表单时,内存使用量都会增加大约 2-5 MB,直到出现 OutOfMemoryException。 我对每个IDisposable 使用using 语句(也用于Forms),尝试清除所有绑定并取消订阅Dispose()中的事件,没有任何改变。 如果我在处理表单后调用GC.Collect(),则使用的内存量会返回之前的状态,就像打开表单之前一样。 我尝试了一些内存分析器,但它们没有显示任何异常。

【问题讨论】:

  • 你在缓存数据吗?
  • 您是否尝试过在分析器中拍摄快照以查看未清除的资源是什么?这可能会给你一个方向
  • 我认为我没有缓存任何数据。我已经拍摄内存快照并分析了一周,但没有发现任何可能表明内存泄漏的东西。
  • 打开表单时加载了多少数据?
  • 在快照之间你看到内存的不同了吗?在它的哪些部分?当然,如果你得到应该反映在快照中的内存异常(可能在非托管资源中)。

标签: c# .net winforms memory-leaks


【解决方案1】:

由于内存增长如此之快,问题一定出在其中一个控件的 Paint 方法中(如果您自己绘制/绘制控件)或在网格的自动更新循环中(如果您更新数据源定期)。

  1. 检查是否在绘制循环中处理了所有画笔、钢笔、字体、字符串格式。
  2. 检查数据源的更新循环。常见错误是未正确处理的 SqlCommand 和 SqlConnections。

希望这会有所帮助。如果没有关于您的源代码的更多详细信息,就很难提供任何其他帮助。

【讨论】:

  • 我认为这些是合理的建议。然而,OP说他确实做了所有这些事情。因此,我认为内存分析器是要走的路。如果它没有显示结果,那么它一定没有被有效地使用。
  • 每个开发人员都认为他在任何地方都使用了 IDisposable。但特别是在绘画/绘画中,你很容易错过一些。但你是对的,使用 NetMemoryProviler、CLRProfiler 或 Yourkit .NET Profiler 等分析器会发现问题。
【解决方案2】:

您的DataSet 可能未正确释放,尽管您已将其丢弃。 来自MSDN

注意:从 DataSet 继承的类不会被垃圾终结 收集器,因为终结器已在 DataSet 中被抑制。这 派生类可以在其内部调用ReRegisterForFinalize 方法 构造函数允许类被垃圾终结 收集器。

你应该阅读这个非常有用的问题Should I Dispose() DataSet and DataTable?

【讨论】:

    【解决方案3】:

    我的雇主 Red Gate Software 制作了一个 .NET 内存分析工具,您可以使用它来调查您的问题。它有一个 14 天的试用期,可能足以免费找到您的泄漏:)

    http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/

    jetBrains 也有 'dotTrace Memory',虽然我没试过。

    【讨论】:

      猜你喜欢
      • 2011-04-22
      • 1970-01-01
      • 1970-01-01
      • 2016-11-02
      • 1970-01-01
      • 1970-01-01
      • 2020-04-02
      • 2010-11-11
      • 1970-01-01
      相关资源
      最近更新 更多