Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GC.SuppressFinalize performance compared to non-finalizable object

Is a finalizable object with GC.SuppressFinalize the same as a normal unfinalizable object? The code below seems to prove they're treated differently, both on .NET 2 and 4:

class Class1 {

    public Class1()
    {
        GC.SuppressFinalize(this);
    }

    //~Class1() { }
}

class Program
{
    static void Main(string[] args)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();

        for (int i=0; i<100000000; i++)
        {
            new Class1();
        }

        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);
    }
}

Adding the finalizer, but not changing anything else, causes the code to take far far longer (12601 ms compared to 889 ms).

I thought SuppressFinalize set a bit in the object header making the GC treat the object the same as a non-finalizable object, but this does not seem to be the case. So what's going on? What is different between a non-finalizable object and a finalizable object with GC.SuppressFinalize called on it?

like image 946
thecoop Avatar asked Mar 28 '12 17:03

thecoop


People also ask

When should I use GC SuppressFinalize?

Once you disposed the object, you should indeed call GC.SuppressFinalize (this);, like shown in an answer to the question "When should I use GC.SuppressFinalize ()?". Code analysis' CA1816 rule is also useful as well. Now, implementing IDisposable on objects which don't have unmanaged resources looks quite weird and questionable.

What is finalization queue in GC?

GC keeps a list (Finalization Queue) of all objects the class of which declares a Finalizer (~ClassName in C#). Objects are put in this queue upon creation. GC runs periodically to check whether there are any objects inaccessible from the program.

What is SuppressFinalize method in Java?

The SuppressFinalize method simply sets a flag in the object header which indicates that the Finalizer does not have to be run. This way GC can reclaim the memory of the object right away.

Is it worthwhile to suppress finalization of an object?

This means that a finalizable object incurs an extra cost: the object must be kept around in memory for a longer time. Hence the call you see: it is worthwhile to suppress finalization when it is not needed. Here, the object uses finalization to ensure that it is always "disposed of" at some point.


Video Answer


1 Answers

As I understand it the CLR has a queue of objects for which finalization has been registered. Implementing a finalizer will put objects of the type on the queue. So in the case where the constructor calls SuppressFinalize, I imagine that the object is actually put on the queue only to be removed immediately, which could explain the overhead.

like image 67
Brian Rasmussen Avatar answered Oct 30 '22 18:10

Brian Rasmussen