Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it legal to recreate a rooted reference to 'this' in a .net destructor?

Is it legal to write the following in .net ?

   public class A
    {
        public int i = 0;
        ~A()
        {
            Aref = this;
        }
    }


    public static A Aref;
    static void Main(string[] args)
    {
        Aref = new A();
        int gen = GC.GetGeneration(Aref);
        Aref = null;
        GC.Collect(gen, GCCollectionMode.Forced);
        GC.WaitForPendingFinalizers();
        Console.WriteLine(Aref.i);
        Console.ReadLine();
    }

It works and writes '0' to the console as expected, but I'm wondering if it's guaranteed to always work.

Does someone know what's happening behind the scene?

like image 805
Brann Avatar asked Jan 24 '23 19:01

Brann


2 Answers

It's called resurrection, and it's legal. Google for ".net object resurrection" (and terms like it) and you'll find stuff like:

Resurrection and the .NET Garbage collector

Object Resurrection

Just make sure these zombie objects don't come back and try to eat your brain or something. Like all necromancy, this is dangerous stuff. (Mostly because the finalizers higher up in the class hierarchy can have released some essential resource. Also note that the finalizer won't be run a second time if the object gets "unreferenced", unless you call GC.ReRegisterForFinalize.)

like image 50
gustafc Avatar answered Jan 29 '23 15:01

gustafc


It works because the first garbage collection doesn't collect the instance. It just schedules the instance to have its finalizer run. The finalizer then creates a new root to the instance, so when the next collection happens the instance is actually rooted and thus not up for collection.

You should be very careful with this tough. If the finalizer is used to make sure an object is disposed, this actually violates the protocol because the disposable patterns says that a disposed instance should throw an ObjectDisposedException if it is used after being disposed.

like image 30
Brian Rasmussen Avatar answered Jan 29 '23 16:01

Brian Rasmussen