我试图弄清楚c#中的GC /终结器是如何工作的,所以我编写了以下程序。但是在ReadKey之后,终结器被称为36193次。我认为应该在程序完成并且AppDomain卸载时调用一次。我在这里缺少什么,这是如何工作的?
private class GCAnalyzer
{
private static int count = 0;
~GCAnalyzer()
{
if (!AppDomain.CurrentDomain.IsFinalizingForUnload())
{
count++;
GC.ReRegisterForFinalize(this);
Console.WriteLine("GC " + count);
}
}
}
static void Main(string[] a)
{
new GCAnalyzer();
Console.ReadKey();
}
答案 0 :(得分:2)
如果我读了这个,那么当对象被“取消链接”时你正在调用~GCAnalyzer(),并且在那段代码中,你说它还没有准备好通过GC.ReRegisterForFinalize(this)“取消链接”,意思是接下来检查它仍然没有使用,它的结束代码运行...重新注册自己......等等。
答案 1 :(得分:0)
关键是添加!Environment.HasShutdownStarted检查。然后在每个集合上调用终结器并将其放回到最终化列表中。所以在这个程序中,终结器被调用3次。每个GC.Collect两次,然后在完成列表中注册,第三次应用程序关闭然后不重新注册,以便它可以正常关闭dow。
private class GCAnalyzer
{
private static int count = 0;
~GCAnalyzer()
{
Console.WriteLine("GC " + count);
if (!AppDomain.CurrentDomain.IsFinalizingForUnload() &&!Environment.HasShutdownStarted)
{
count++;
GC.ReRegisterForFinalize(this);
}
}
}
static void Main(string[] a)
{
new GCAnalyzer();
Console.ReadKey();
GC.Collect();
Console.ReadKey();
GC.Collect();
}