【问题标题】:System.OutofMemory exceptionSystem.OutofMemory 异常
【发布时间】:2012-09-27 04:56:43
【问题描述】:

我有一个 UI,winform,它有很多控件,如 tabcontrols、大量文本框(跨选项卡至少 25 个)组合框、复选框、按钮、标签、树形控件等。

这些控件中的大多数都注册了 ctrl 事件,例如 textchanged、click 等... 由于我遇到了内存不足异常,而且我几乎没有什么疑问:

问题:

  1. 在表单的 dispose 函数中应该调用每个这个 ctrl 的 dispose 吗?
  2. 是否应该在 dispose 函数中取消注册由 ctrls 订阅的事件,如 textchanged、click 事件等? GC 是否负责取消注册为 ctrls 添加的事件,因为在设计器中添加了代码 sn-ps?

一些信息: 该应用程序在 2GB 内存机器上进行了多达 100 次迭代的稳定性测试。每次迭代它都会执行相同的测试(启动对话框,进行一些点击或编辑一些值,然后关闭)。它运行了将近8个小时。在第 45 次或第 46 次迭代时,它抛出了这个异常。是的,对话框中的所有控件都注册了一个事件或其他事件。一些文字改变了一些checkedchanged或点击等

【问题讨论】:

  • 信息不足。发生此异常时,您的应用程序在做什么?它运行了多长时间?是否所有控件都已连接事件?
  • 嗯,这个应用程序在 2GB 内存机器上进行了多达 100 次迭代的稳定性测试。每次迭代它都会执行相同的测试(启动对话框,进行一些点击或编辑一些值,然后关闭)。它运行了将近8个小时。在第 45 次或第 46 次迭代时,它抛出了这个异常。是的,对话框中的所有控件都注册了一个事件或其他事件。一些文字改变了一些checkedchanged或点击等。
  • 使用托管代码很可能会泄漏内存。您可以在“C# 内存泄漏”或“C# 事件处理程序泄漏”之类的内容上搜索 SO 或只是 google。

标签: c# winforms


【解决方案1】:

我认为这里没有足够的信息来告诉你到底发生了什么。这需要您对代码进行一些仔细的分析,但首先要做的是通过内存分析器运行您的应用程序。例如,ANTS Memory Profiler,但实际上你可以访问的任何东西都可以)看看到底发生了什么。

通常,您不需要显式处理每个控件,但如果您订阅事件,这可能会导致事情在内存中停留的时间比平时更长。 This question 有血淋淋的细节,但简而言之,你想取消订阅或使用弱引用来解决这个问题;无需枚举所有表单控件并调用Dispose。如果我记得的话,无论如何都应该在 Form.Close() 上调用它,除非它是 MDI 表单并且在调用 Close 时它不可见。

您还应该查看您正在存储哪些数据以及如何存储,以及您是否正确处理了您的应用程序可能使用的任何资源。

如果您在 32 位系统上运行,您可能还会遇到 2GB 的每个进程内存限制,如果您保持List 大约增长到 1GB 并且必须调整大小。

所以,用探查器武装自己并开始调查。 :)

【讨论】:

    猜你喜欢
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多