ARTICLE

Resurrection and the .NET Garbage collector

Posted by Ravi Ramnath Articles | Articles C# July 13, 2001
This article will explain and demonstrate a phenomenon that is unusual in the .NET implementation of the garbage collector. The phenomenon is known as resurrection. As the name suggests, an object is marked for destruction and in the last possible moment it is resurrected from the ‘dead’ and reactivated.
Reader Level:
Download Files:
 

This article will explain and demonstrate a phenomenon that is unusual in the .NET implementation of the garbage collector. The phenomenon is known as resurrection. As the name suggests, an object is marked for destruction and in the last possible moment it is resurrected from the dead and reactivated.

using system;
public class B
{
static public A IntA;
}
public class A
{
private int x = 10;
public void DoIt()
{
Console.WriteLine( "Value : {0}", x );
}
~A()
{
B.IntA =
this;
}
}
public class Test
{
static void Main()
{
A a =
new A();
a.DoIt();
a =
null;
GC.Collect();
B.IntA.DoIt();
}
}
 
Figure 1
In the sample code, class B has a static member reference to class A. In class A, its destructor assigns its this pointer to class Bs static member IntA. In function Main, an instance of A is created and then set to null. The code then forces a garbage collection to occur. At this point, the garbage collector will determine that object a is not reachable and should therefore mark the object for cleanup. Note that the object is not immediately deleted because it has a destructor. When next the garbage collector runs, it calls the destructor for object a. In the destructor, class A saves its reference in B. This forces the garbage collector to not kill the object because the object is now reachable from another live object ( namely object B ). Hence, the object a is resurrected.

In the sample code, I call a method DoIt to demonstrate that you can still call methods on a resurrected object. 

If you had to now set B.IntA = null, and force the runtime to kill object a, the destructor will not be called for the object a. You must call System.GC.ReRegisterForFinalization()  to register for finalization e.g. 

  ~A()
  {
    B.IntA = this;
        System.GC.ReRegisterForFinalize (this);
  }

Also, note that the danger of using resurrection is that if you had handles to system resources, your destructor would have freed them. To re-use a resurrected object can cause unexpected results if you do not re-allocate those handles e.g. files would have been closed, etc.

COMMENT USING

Trending up