复活后的GC生成?

Roy*_*mir 6 .net c# garbage-collection

假设一个对象有一个Finalize()方法.

首次创建时,添加了终结队列中的指针.

该对象没有引用.

发生垃圾收集时,它会将引用从最终化队列移动到f-reachable队列,并启动一个线程来运行该Finalize方法(按顺序执行其他对象的Finalize方法).

所以现在(复活后)对象只有一个根,它是来自f-reachable队列的指针.

在这一点上,对象是否/被提升到下一代?

Han*_*ant 3

这是你可以尝试的事情。在不附加调试器的情况下在发布版本中运行此代码:

using System;

class Program {
    static void Main(string[] args) {
        var obj = new Foo();
        // There are 3 generations, could have used GC.MaxGeneration
        for (int ix = 0; ix < 3; ++ix) {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
        Console.ReadLine();
    }
}

class Foo {
    int attempt = 0;
    ~Foo() {
        // Don't try to do this over and over again, rough at program exit
        if (attempt++ < 3) {
            GC.ReRegisterForFinalize(this);
            Console.WriteLine(GC.GetGeneration(this));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
2

因此,它保留在集合移动到的一代中,移动到每个集合的下一个集合,直到到达最后一个集合。一般来说这是有道理的。