Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's circular reference destruction sequence

Here I have declared two types A,and B,and they have reference to each other

public class A
{
    public B B { get; set; }

    ~A()
    {
        Console.WriteLine( "destructing A..." );
    }
}

public class B
{
    public A A { get; set; }

    ~B()
    {
        Console.WriteLine( "destructing B..." );
    }
}

in Main method,

    var b = new B();
    var a = new A();
    a.B = b;
    b.A = a;
    a = null;
    b = null;
    GC.Collect();

the output shows that the destruction order is exactly as their definition order,I'm wondering why is that?

like image 494
Chris Avatar asked Dec 03 '25 15:12

Chris


2 Answers

There is no guaranteed order for finalizers:

The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other. That is, if Object A has a reference to Object B and both have finalizers, Object B might have already been finalized when the finalizer of Object A starts. Object.Finalize

With an exception for critical finalizers:

In addition, the CLR establishes a weak ordering among normal and critical finalizers: for objects reclaimed by garbage collection at the same time, all the noncritical finalizers are called before any of the critical finalizers. CriticalFinalizerObject

like image 130
user4003407 Avatar answered Dec 06 '25 05:12

user4003407


Garbage Collection in .NET is non-deterministic (as you have observed since you are calling GC.Collect). There is no guarantee regarding the order of finalization whatsoever.

Yes, this means that referenced objects can be finalized before objects referencing them. That's one of the reasons writing a finalizer is very hard. You might work on "deinitialized" state.

Try not to use finalizers at all. It is extremely rare to need them.

like image 25
usr Avatar answered Dec 06 '25 06:12

usr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!