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

当CLR在.net中调用垃圾收集器时?,.net,garbage-collection,clr,.net,Garbage Collection,Clr,谁能告诉我垃圾收集器什么时候被叫到?它是否继续在后台线程中运行?垃圾收集器如何知道我必须从几代中清理内存?垃圾收集器没有连续运行;它一次运行一个“集合”(这可能会影响多个GC“生成”) 调用它时(忽略GC.Collect())是不确定的,我认为这是CLR的一个实现细节,而不是规范的一部分 也就是说,只要程序试图在托管堆中分配内存,并且没有足够的连续可用内存来分配内存,当前的.NET GC就会运行。集合释放空间并对堆的内容进行碎片整理,留下空间来执行分配 任何在Gen0集合中幸存的内容都将升级到G

谁能告诉我垃圾收集器什么时候被叫到?它是否继续在后台线程中运行?垃圾收集器如何知道我必须从几代中清理内存?

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

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

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


任何在Gen0集合中幸存的内容都将升级到Gen1;如果Gen1中没有足够的空间用于升级项目,则也会收集Gen1。Gen1和Gen2之间也会发生同样的情况。

如果您想知道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!
        }
    }
}

该类在GC完成时实例化自身。此外,当GC启动时,它会打印一条消息


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

垃圾收集器运行:

  • 当代码试图分配内存时,堆上没有足够的空间
  • 当系统向应用程序发送信号以尝试使用较少的资源时(例如,当您最小化应用程序时)
  • 每当垃圾回收器认为它有用时,例如,如果堆空间所剩无几,而您的应用程序正忙于执行磁盘I/O,则垃圾回收器可能会有用
例如,垃圾收集器如何确定何时应该运行是一个实现细节,因此它可以在框架的不同版本之间有所不同

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

  • 当第0代对象将达到约256 KB时
  • 当第1代对象将达到~2Mb时
  • 当第2代对象将达到~10Mb时
  • 当系统内存不足时

它何时被调用取决于许多事情。Microsoft在垃圾收集器方面有很好的文档摘要:。