谁能告诉我垃圾收集器何时被调用?它是否继续在后台线程中运行?垃圾收集器如何知道我必须清理内存形式的世代?
4 回答
If you want to know exaclty if the GC is collecting, you can use this class:
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!
}
}
}
The class instantiates itself when it is getting finalized by the GC. Also, it prints a message when the GC kicks in.
Also you can take a look at the links posted in the comments to get a deep-dive into the .NET GC here and here.
垃圾收集器运行:
- 当您的代码尝试分配内存时,堆上没有足够的空间。
- 当系统向应用程序发送信号以尝试使用更少的资源时(例如,当您最小化应用程序时)。
- 每当垃圾收集器觉得它很有用时,例如,如果剩下的堆空间很少,而您的应用程序无论如何都忙于进行磁盘 I/O,则可能是这样。
垃圾收集器如何确定它应该何时运行是一个实现细节,因此它可能在框架版本之间有所不同。
垃圾收集器不会连续运行。当它运行时,应用程序中的所有其他线程都被冻结,因此垃圾收集器可以单独控制内存。
垃圾收集器没有连续运行;它一次运行一个“集合”(这可能会影响多个 GC“代”)。
当它被调用时(忽略GC.Collect()
)是不确定的,我相信它是 CLR 的实现细节,而不是规范的一部分。
也就是说,只要程序尝试在托管堆中分配内存并且没有足够的连续可用内存来执行此操作,当前的 .NET GC 就会运行。集合释放空间并对堆的内容进行碎片整理,留下空间来执行分配。
任何在 Gen0 集合中幸存下来的东西都被提升为 Gen1;如果 Gen1 中没有足够空间用于提升项目,则 Gen1 也会被收集。Gen1 和 Gen2 之间也是如此。
- 当 Gen 0 对象将达到 ~ 256 KB 时。
- 当 Gen 1 对象将达到 ~ 2Mb 时。
- 当第 2 代对象将达到 ~ 10Mb。
- 当系统内存不足时。