【问题标题】:When CLR calls Garbage collector in .net?当 CLR 在 .net 中调用垃圾收集器时?
【发布时间】:2012-10-26 07:30:38
【问题描述】:

谁能告诉我垃圾收集器何时被调用?它是否继续在后台线程中运行?垃圾收集器如何知道我必须清理内存形成代?

【问题讨论】:

标签: .net garbage-collection clr


【解决方案1】:

如果你想知道 GC 是否正在收集,你可以使用这个类:

public class GCWatcher
{
    protected override void Finalize()
    {
        Debug.Print("GC on the prowl");
        try {
            if (!AppDomain.CurrentDomain.IsFinalizingForUnload() && !Environment.HasShutdownStarted) {
                GCWatcher g = new GCWatcher();
            }
        } catch {
            // nothing to do, but in case of error, the GC should continue anyway!
        }
    }
}

Source

该类在被 GC 终结时实例化自己。此外,它会在 GC 启动时打印一条消息。

您还可以查看 cmets 中发布的链接,深入了解 .NET GC herehere

【讨论】:

    【解决方案2】:

    垃圾收集器运行:

    • 当您的代码尝试分配内存时,堆上没有足够的空间。
    • 当系统向应用程序发送信号以尝试使用更少的资源时(例如,当您最小化应用程序时)。
    • 每当垃圾收集器觉得它有用时,例如,如果剩余的堆空间很少,而您的应用程序正忙于执行磁盘 I/O。

    垃圾收集器如何确定它应该何时运行是一个实现细节,因此它可能因框架版本而异。

    垃圾收集器不会连续运行。当它运行时,应用程序中的所有其他线程都被冻结,以便垃圾收集器可以单独控制内存。

    【讨论】:

      【解决方案3】:

      垃圾收集器没有连续运行;它一次运行一个“集合”(这可能会影响多个 GC“代”)。

      何时调用(忽略 GC.Collect())是不确定的,我认为是 CLR 的实现细节,而不是规范的一部分。

      也就是说,只要程序尝试在托管堆中分配内存并且没有足够的连续可用内存来执行此操作,当前的 .NET GC 就会运行。集合释放空间并对堆的内容进行碎片整理,留下空间来执行分配。

      任何在 Gen0 集合中幸存的东西都被提升为 Gen1;如果 Gen1 中没有足够空间用于提升项目,则 Gen1 也会被收集。 Gen1 和 Gen2 之间也是如此。

      【讨论】:

        【解决方案4】:
        • 当 Gen 0 对象将达到 ~ 256 KB 时。
        • 当第 1 代对象将达到 ~ 2Mb 时。
        • 当第 2 代对象将达到 ~ 10Mb 时。
        • 当系统内存不足时。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-04
          • 1970-01-01
          相关资源
          最近更新 更多