当CLR在.net中调用垃圾收集器时?

时间:2012-10-26 07:30:38

标签: .net garbage-collection clr

任何人都可以告诉我垃圾收集器何时被调用?它是否在后台线程中持续运行?垃圾收集者如何知道我必须清理几代人的记忆?

4 个答案:

答案 0 :(得分:3)

如果你想知道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启动时打印一条消息。

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

答案 1 :(得分:2)

垃圾收集器运行:

  • 当你的代码试图分配内存时,堆上没有足够的空间。
  • 当系统向应用程序发送信号以尝试使用更少的资源时(例如,当您最小化应用程序时)。
  • 每当垃圾收集器认为它有用时,例如,如果剩下很少的堆空间并且你的应用程序正在忙着执行磁盘I / O,那么这就好了。

垃圾收集器如何确定它应该运行的时间是一个实现细节,因此它可以在框架版本之间有所不同。

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

答案 2 :(得分:1)

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

当它被调用时(忽略GC.Collect())是非确定性的,我相信是CLR的实现细节,而不是规范的一部分。

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

Gen0集合中存活的任何内容都会升级为Gen1;如果Gen1中没有足够的空间用于促销项目,则也会收集Gen1。 Gen1和Gen2之间也是如此。

答案 3 :(得分:0)

  • 当Gen 0对象达到~256 KB时。
  • 当Gen 1对象达到〜2Mb。
  • 当Gen 2对象达到~10Mb。
  • 当系统内存不足时。