【问题标题】:Is there a way to know what keeps objects alive in C#有没有办法知道是什么让 C# 中的对象保持活力
【发布时间】:2010-08-07 23:02:32
【问题描述】:

我正在尝试优化程序的内存使用,因此希望在不再需要对象时删除它们。为了检查这是否正常工作,我在要删除的对象类型的析构函数中编写了一个 console.writeline 方法。但是,当我测试程序时,没有写入任何行(当然只有在程序终止时)。

有没有办法获取对象、事件、...的列表,让某个对象保持活动状态并防止它被垃圾收集器清除。或者是否有一个分析器、调试器可以做到这一点(如果可能的话,与 MonoDevelop 兼容)?

【问题讨论】:

    标签: c# pointers reference garbage-collection


    【解决方案1】:

    WinDbg + SOS 可以帮助理解这一点。但这需要时间来学习。例如,

    Where's your leak at? [Using WinDbg, SOS, and GCRoot to diagnose a .NET memory leak]

    【讨论】:

      【解决方案2】:

      清理的发生是由系统控制的,如果你的内存分配足够小并且系统认为没有必要清理,那么你的析构函数就不会被调用。 这不是生产的最佳实践,但您可以通过 GC.Collect() 强制 GC 仅在测试中使用它。如果没有调用您的析构函数,则可能存在泄漏。

      我不知道单声道环境中的分析器,但 this profiler 在 Windows 中已经足够好了。

      【讨论】:

      • 注意不要将 GC.Collect() 用作通用清理工具。它实际上可以通过将尚未准备好收集的对象移动到更高阶的一代来使内存使用更糟,这样它们将来就更难收集了。
      • @Joel Coehoorn,绝对同意!我写了这不是生产的最佳实践,如果你想让你的析构函数被 GC 调用。
      【解决方案3】:

      .NET 垃圾收集器将自动清理(释放)不再引用的对象。但是,程序具有静态字段、未删除的事件处理程序或其他导致对象保持活动(并使用内存)的时间超过严格必要的时间的情况并不少见。

      要解决此问题,请使用内存分析器来识别保存对象的“根”,找出它们仍被引用的原因,并修复导致对象仍被引用的错误。

      一些商业和免费的内存分析器是:

      【讨论】:

        【解决方案4】:

        释放资源占用资源。如果垃圾收集器没有检测到正在使用的内存过多,它就不会释放其资源。如果您需要确定性的“析构函数”,请实现 IDisposable。另见 "using" keyword

        【讨论】:

        • IDisposable 和 using 永远不会释放任何内存(当然,除非该内存由非托管(外部)代码持有)。
        最近更新 更多