Whilst 'investigating' finalisation (read: trying stupid things) I stumbled across some unexpected behaviour (to me at least).
I would have expected the Finalise method to not be called, whereas it gets called twice
class Program
{
static void Main(string[] args)
{
// The MyClass type has a Finalize method defined for it
// Creating a MyClass places a reference to obj on the finalization table.
var myClass = new MyClass();
// Append another 2 references for myClass onto the finalization table.
System.GC.ReRegisterForFinalize(myClass);
System.GC.ReRegisterForFinalize(myClass);
// There are now 3 references to myClass on the finalization table.
System.GC.SuppressFinalize(myClass);
System.GC.SuppressFinalize(myClass);
System.GC.SuppressFinalize(myClass);
// Remove the reference to the object.
myClass = null;
// Force the GC to collect the object.
System.GC.Collect(2, System.GCCollectionMode.Forced);
// The first call to obj's Finalize method will be discarded but
// two calls to Finalize are still performed.
System.Console.ReadLine();
}
}
class MyClass
{
~MyClass()
{
System.Console.WriteLine("Finalise() called");
}
}
Could anyone explain whether this behaviour is intentional and if so why?
This above code was compiled in x86 debug mode and running on the CLR v4.
Many thanks
if
statement in the internalReRegisterForFinalize()
method that says "if I've been marked as finalized, remove that mark. If not, just add me to the queue." So if you call ReReg twice without supressing first, the object just gets added to the queue twice. Then, suppress clears the bit three times (which does nothing, really, since the bit was never set to begin with!) In any case, brilliant speculation, as always. – Susurrous