GC generation after resurrection?

.net, c#, garbage-collection

Solution

This is something you can just try. Run this code in the Release build without a debugger attached:

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));
        }
    }
}

Output:

1 2 2

So it stays in the generation it got moved to by the collection, moving to the next one on each collection until it hits the last one. Which makes sense in general.

Problem

Suppose an object has a `Finalize()` method. When it is first created, a pointer in the finalization queue was added. The object has no references . When a garbage collection occurs, it moves the reference from the finalization queue to the f-reachable queue and a thread is started to run the `Finalize` method (sequentially after other objects' `Finalize` methods). So the object now (after resurrection) has only one root which is the pointer from the f-reachable queue. At this point, does/did the object get promoted to the next generation ?

Original source