locked
Finalizer thread semantic RRS feed

  • Question

  • In a previous post, I was describing a weird problem encountered within the finalizer thread.

    Basically, within a finalizer I was doing quite a lot of work (complicated side effects, not simply cleaning few ressources), and I did encounter some weird CLR behavior. I am actually wondering about the semantic of the finalizer thread.

    First, I guess that intercepting the finalizer thread to do any real work is a bad idea because it blocks the garbage collection from running. Therefore, I have opted, within my finalizer method, to queue the side-effect works in the ThreadPool. Now my finalizer is non blocking. Additionnaly the side effects are run through a thread of the ThreadPool, and I know that those threads do not have any particularity (just conventionnal Thread). What do think of this design pattern?

    Second is a question about the finalizer thread: does the finalizer thread count as a root for the GC ? This point is not clear for me. I would be tempted to say no, because precisely the GC requires the threads to be stopped in order to have a consistent view of the memory to perform the collection. In the other hand, if the finalizer thread is not root, then one can expect very weird .Net behavior during the execution of the finalizer method.

    If someone can provide me information of those points, it would be of great help.

    Thanks in advance,
    Joannès
    Sunday, September 11, 2005 11:37 AM

Answers

  • Assuming you really need Finalizers in the first place (most of the time this is not a good approach) scheduling some work on threadpool may have a merit. In fact according to Chris Brumme http://blogs.msdn.com/cbrumme/archive/2004/02/20/77460.aspx
    CLR may in the future schedule Finalizers on a thread pool.
    Note however that priority of finalizer and threads in a threadpool will be different.

    Second question:
    Check the great 2 part article by Jeff Richter
    http://msdn.microsoft.com/msdnmag/issues/1200/gci2/
    Basically freachable queue (object whose finalizer is scheduled to be executed) is the root that keeps your objects alive (but maybe already disposed)
    Nothing to do with stoping any threads.

    Monday, September 12, 2005 5:20 PM

All replies

  • Assuming you really need Finalizers in the first place (most of the time this is not a good approach) scheduling some work on threadpool may have a merit. In fact according to Chris Brumme http://blogs.msdn.com/cbrumme/archive/2004/02/20/77460.aspx
    CLR may in the future schedule Finalizers on a thread pool.
    Note however that priority of finalizer and threads in a threadpool will be different.

    Second question:
    Check the great 2 part article by Jeff Richter
    http://msdn.microsoft.com/msdnmag/issues/1200/gci2/
    Basically freachable queue (object whose finalizer is scheduled to be executed) is the root that keeps your objects alive (but maybe already disposed)
    Nothing to do with stoping any threads.

    Monday, September 12, 2005 5:20 PM
  • Hi Joannès

    As you've guessed, you should avoid doing any non-trivial work in the finalizer.  The reason is not that it blocks the GC from running (it doesn't), but that it blocks any further finalizers from being run, which has the side-effect of all objects on the finalizer list not being collected (since their finalizers haven't run yet).

    The problem I can imagine with your ThreadPool design (based on your description), is that you are relying on other finalizable objects from your finalizer.  This is dangerous since the order finalizers are run is not deterministic, so your ThreadPool's threads, etc may be finalized before your object.

    About your second question: the finalizer thread is not a GC root, but the freachable list is (see the links dimkaz pointed you to).  You are correct, you can expect "weird" behaviour on the finalizer thread.  There are limitations to what you should do in your finalizer, as Chris Brumme points out.  A short list includes: don't block, don't reference other finalizable objects, don't throw exceptions, etc.

    What is the reason you feel you need to use finalizers?  They are an unreliable solution to any problem beyond the clean up of unmanaged resources.

    Hope that helps

    -Chris [MS]

    Monday, September 12, 2005 5:55 PM
  • Thanks for those answers. Well, normally the side effects does not involve any other finalizable objects, therefore the lack of determinism of finalization should not be an issue.

    To answer question concerning the need for finalizer, I am currently designing a distributed garbage collector for a distributed programming framework. I need to intercept the death of the distributed objects.

    Joannès
    Monday, September 12, 2005 7:10 PM