.NET, C#, CLR, GarbageCollection

What do you know about Freachable queue?

How Garbage Collection in CLR works

I was reading two excellent articles about Garbage Collection in .NET, you can the first part here and the second part here . They are a bit of a long read, but I strongly suggest you read them both carefully. A lot of eye opening stuff. Seriously, you should stop reading this scribblings now and go read the real knowledge! What surprised me most is the way a Finalization is handled and how the freachable queue works.

Freachable Queue

Freachable what? You might ask. Freachable (pronounced F-reachable) is one of CLR Garbage Collector internal structures that is used in a finalization part of garbage collection. You might have heard about the Finalization queue where every object that needs finalization lands initially. This is determined based on whether he has a Finalize method, or it’s object type contains a Finalize method definition to speak more precisely. This seems like a good idea, GC wants to keep track of all objects that he needs to call Finalize on, so that when he collects he can find them easily. Why would he need another collection then? Well apparently what GC does when he finds a garbage object that is on Finalizable queue, is a bit more complicated than you might expect. GC doesn’t call the Finalize method directly, instead removes object reference from Finalizable queue and puts it on a (wait for it.. ) Freachable queue. Weird, huh? Well it turns out there is a specialized CLR thread that is only responsible for monitoring the Freachable queue and when GC adds new items there, he kicks in, takes objects one by one and calls it’s Finalize method. One important point about it is that you shouldn’t rely on Finalize method being called by the same thread as rest of you app, don’t count on Thread Local Storage etc. But what interest me more is why? Well the article doesn’t give an answer to that, but there are two things that come to my mind. First is performance, you obviously want the garbage collection to be as fast as possible and a great deal of work was put into making it so. It seems only natural to keep side tasks like finalization handled by a background thread, so that main one can be as fast a possible. Second, but not less important is that Finalize is after all a client code from the GC perspective, CLR can’t really trust your dear reader implementation. Maybe your Finalize will throw exception or will go into infinite loop? It’s not something you want to be a part of GC process, it’s much less dangerous if it can only affect a background thread.

Prolonging objects life

What is even more interesting is that since a pointer to a garbage is now added to a freachable queue, it means that an object is no longer a garbage! How come? Well a garbage is an object that has no pointer “pointing” to it from the application roots, this used to be true, but now we need to keep a reference to call Finalize. That’s how the queue got it’s name, it’s f(inalize)-reachable, has objects that need to be finalized and can be reached. It also means that freachable queue is treated as a part of application roots the same way as global, static or instance fields, variables etc. So an object is alive again, resurrected! GC cannot reclaim it’s memory, since it’s no longer garbage. This might sound like a funny little detail, but what it really means is that every time you override Finalize method in your object it will be artificially prolong your object’s life by one GC generation!! Only after next collection, if the special thread already processed this object, can your object be collected and it’s memory freed. Probably not what you had in mind, right?
Is there something we can do about it? Sure, try to always clean after yourself without waiting for GC to call finalize on your objects by ( implementing IDisposable and using “using” block for instance) and always call GC.SupressFinalize when you do that.


public void Dispose()
        {
            //clean your resources
             ...
            //let GC know about it
            GC.SuppressFinalize(this);
        }

 

All GC.SuppressFinalize does is set a flag on object Finalizable queue entry, leting GC know that Finalize call is no longer needed. You should always implement IDisposable in that way. Like the msdn page about IDisposable says btw

Ressurection

A little trick you can do with this knowledge, is that since your object got resurrected you can actually keep him alive for longer if you want. All you really have to do is implement Finalize to store reference to this object somewhere in application roots and that’s it.

public class ZombieObject {

    protected override void Finalize() { 
        Application.ZombieHolder = this;  //assuming your Application class has a proper ZombieHolder property
    }
}

 

You brought him back from dead, messiah! Not only him, if he had some child object they will be ressurected as well, as they are now part of Application Roots. One important note here, since the object in question was already removed from Finalization queue when it was collected the first time, it’s finalize method won’t be called again if it becomes garbage in the future. If you want to create a truly indestructible (incollectable? ) object you need to re-register him for finalize again:

public class VampireObject {

    protected override void Finalize() { 
        Application.VampireHolder = this;  //assuming your Application class has a proper ZombieHolder property
        GC.ReRegisterForFinalize(this);    //tell GC this object needs finalization
    }
}

 

That way every time it gets finalized it starts as if it was a young, newly created object! This is a very fascinating mechanism and a neat trick, but please don’t use it in your production code! This can bring a lot of unpredictable results as you might end up using already finalized objects if your object has child objects, there is no guaranteed order in which they get finalized! Also, I can only imagine how WTF-per-minute metric might skyrocket when someone tries to debug code like this!
So please don’t!

Advertisements
Standard

One thought on “What do you know about Freachable queue?

  1. Pingback: Testing GC Eligibility of Objects in C# - Journey of Code

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s