Friday, April 23, 2010

Finalizer in .NET

Besides we have .NET Garbage Collection to do the memory cleanup. But still in some cases you may wish to have your own Finalizer to do the cleanup.

There are some questions around it.

1 -When do I need to implement a finalizer on my class?
2- Should I always do it, or only when I'm holding onto unmanaged resources?
3- Should I always implement the IDisposable interface when I have a finalizer, and vice versa?

Explaination:-


Finalizers only need to be implemented when you hold onto resources that need cleaning up. For example, a FileStream which holds onto a native file handle. Unfortunately, finalizers place a significant amount of performance-hit and pressure on the GC and should be used only when it is absolutely needed.

What is IDisposable

The IDisposable interface allows users of your class to deterministically (as you know GC is Non-deterministic) do the clean-up. Therefore, any class that implements a finalizer should also implement IDisposable.

Scenarion: - Consider a scenario where my managed class has a FileStream as a private member. FileStream holds onto unmanaged resources and implements both IDisposable and a finalizer. When no more references to the instance exist, this FileStream will be similarly unreachable and will be available for finalization.

There's no reason for my class to be in the queue of objects that have registered for finalization since the instance of FileStream will be there. But my class should provide a way for a user to immediately release all resources it holds onto, either directly or indirectly, and therefore my class should implement IDisposable.

My implementation of Dispose will simply call the FileStream's Dispose method. Note, though, that you need to be careful not to dispose of shared resources (resources used by other instances, for example).

If you write a class that will dispose of a resource made available to it from an external source, make sure your documentation is clear on the subject so that others know whether they're handing over control of any resources they give you.

How to implement Dispose


If you do need to implement a finalizer in your class, your Dispose method should use the GC.SuppressFinalize method to ensure that finalization of your instance is suppressed.

This will remove the instance from the set of objects that require finalization, reducing the pressure on the GC during the collection process through heap.

A common pattern implemented throughout the Microsoft® .NET Framework is to add to a class a Dispose method that takes a Boolean as a parameter.

This Boolean indicates whether the class is being disposed because the IDisposable.Dispose method is called or because the finalizer is run (both the finalizer and IDisposable.Dispose delegate to this method).

If it's being disposed deterministically, GC.SuppressFinalize is invoked. If it's being called from a finalizer, avoid using managed members of your class that implement finalizers as they may have already been finalized.

2 comments:

sampada said...

For once I was asked what is the difference between finalize() and dispose() methods. On reading this article, my understanding is that both methods perform similar tasks but with finalize() one can not be sure when GC will be invoked and when the unmanaged resources will be released but with dispose method it is sure that the resources will be released at a particular point. Please correct me if I am wrong.

Bellevue .NET User Group said...

Sampada, you are right. Finalize is to be picked up by the GC during cleanup process.

But Dispose() is user can invoke from Intellisence.