【发布时间】:2012-10-26 07:30:38
【问题描述】:
谁能告诉我垃圾收集器何时被调用?它是否继续在后台线程中运行?垃圾收集器如何知道我必须清理内存形成代?
【问题讨论】:
-
何时调用取决于很多事情。微软在垃圾收集器上有很好的文档:msdn.microsoft.com/en-us/library/0xy59wtx.aspx。
标签: .net garbage-collection clr
谁能告诉我垃圾收集器何时被调用?它是否继续在后台线程中运行?垃圾收集器如何知道我必须清理内存形成代?
【问题讨论】:
标签: .net garbage-collection clr
如果你想知道 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 启动时打印一条消息。
【讨论】:
垃圾收集器运行:
垃圾收集器如何确定它应该何时运行是一个实现细节,因此它可能因框架版本而异。
垃圾收集器不会连续运行。当它运行时,应用程序中的所有其他线程都被冻结,以便垃圾收集器可以单独控制内存。
【讨论】:
垃圾收集器没有连续运行;它一次运行一个“集合”(这可能会影响多个 GC“代”)。
何时调用(忽略 GC.Collect())是不确定的,我认为是 CLR 的实现细节,而不是规范的一部分。
也就是说,只要程序尝试在托管堆中分配内存并且没有足够的连续可用内存来执行此操作,当前的 .NET GC 就会运行。集合释放空间并对堆的内容进行碎片整理,留下空间来执行分配。
任何在 Gen0 集合中幸存的东西都被提升为 Gen1;如果 Gen1 中没有足够空间用于提升项目,则 Gen1 也会被收集。 Gen1 和 Gen2 之间也是如此。
【讨论】:
【讨论】: