Поделиться через


Understanding when to use a Finalizer in your .NET class

A common problem we see when moving to .NET all revolves around the finalizer.  There are a few reasons that this happens:

  • Developers move from C/C++ to C# and are used to created classes with a constructor and destructor.
  • Developers don’t understand when they need to implement Dispose or Finalize and thus create them when they aren’t needed.

Finalization – what is it?

So what is Finalization and why is this such an important thing to understand?  Well, there is a good description of it found here.  Basically it is a way to make sure some code runs when an object gets cleaned up.

Why is it necessary?

If an object holds onto any unmanaged resources, such as file handles, sockets or database connections, the object is responsible for cleaning them up when it is destroyed.  This only applies to unmanaged resources!

I would very strongly recommend that you read the documentation for the Finalize object very carefully before you use it.  The things to watch for are:

  1. If you use an unmanaged object and hold a reference to it, you must implement a Finalizer to allow that unmanaged object to be cleaned up.  Otherwise you will leak unmanaged (heap) memory.
  2. If you create a Finalize method (~Class in C#), even if it is empty, this will put the object on the finalize queue.
  3. If you have a Finalize method, don’t try to clean up managed objects from it.  That is why most Finalize methods call Dispose(false).  So they don’t clean up any managed objects.  This is because finalized can happen in any order and just cause you hold a reference to an object, doesn’t mean it hasn’t been cleaned up already.

Why is a Finalize method bad?

So now we know how we should use the finalizer, but why is it so important to do it correctly?  So items 1 and 3 above are pretty explanatory as to why you would want to do that.  So what is wrong with #2?

If an object has a finalizer, it will be placed in the FinalizationQueue and is subject so some additional clean-up.  Once the object is no longer referenced on a thread or from a global reference, the next time the Garbage Collector (GC) runs, it will see this object is ready to be collected.  But it can’t collect it yet.  It has to let the Finalizer run first.  So the GC will finish collecting, then the Finalizer will Finalize the object, and then another GC collection will occur.

This can have a huge affect on performance as you should remember that all managed threads will be stopped waiting on the GC and then the GC will be stopped waiting on the Finalizer thread.

There is a lot more data out there about Finalization so I encourage you to read about it as much as possible so that you use it in the best way possible.

kick it on DotNetKicks.com

Comments

  • Anonymous
    April 25, 2008
    You've been kicked (a good thing) - Trackback from DotNetKicks.com

  • Anonymous
    April 25, 2008
    If you are going to use a finalizer in your .NET class, be sure to read this post so that you understand

  • Anonymous
    April 26, 2008
    Your last few sentences are slightly inaccurate.  When GC occurs, the object will be placed on the finalizer thread's queue.  At this point GC doesn't wait for the finalizer thread to run the finalizer - it completes normally.  When the finalizer thread runs the finalizer and another GC occurs, the object will be collected.  So the primary thing to note is that GC doesn't wait for the finalizer.

  • Anonymous
    April 26, 2008
    Finalization is one of the most complicated and obscure areas of .NET. Most developers don't actually

  • Anonymous
    April 27, 2008
    Link: Understanding when to use a Finalizer in .NET

  • Anonymous
    April 28, 2008
    The comment has been removed

  • Anonymous
    April 28, 2008
    Sasha, Very true, I corrected the post on that.  Thanks for finding it.

  • Anonymous
    April 28, 2008
    GProssLiner, thanks for the additional notes.  All very important.  I corrected the mistake about the GC.  Thanks for finding it.

  • Anonymous
    April 28, 2008
    So in a previous post, we talked about Understanding when to use a Finalizer in your .NET class so now