Good Finalize/Dispose Pattern

This is the approach one should follow to clean up internal unmanaged resources. Remember one thing you should use this only if make use of some unmanaged stuff that you want to be cleaned up before your application closes in a better way so that there are no leaks. If you are just using all managed stuff then you should not need to write Finalize() methods only Dispose() pattern would work. Else GC is very intelligent itself to handle all the stuff & auto optimize itself. Rest being said lets focus on practical example that what should we follow in order to write robust code.

Let us say we have some class that does a bit of work with unmanaged types. We follow both the finalize & dispose patterns so that if the user forgot’s to call Dispose(), then the garbage collector cleans up the stuff by calling finalize(), & as long as user dispose off objects, the garbage collector doesn’t need to finalize things. So in this model, we have best technique & doesn’t end up with leaking things. But remember if we are disposing things ourselves then we can afford to call other managed types around & dispose them too if required but if Garbage Collector does Finalize() the object then we can’t reference or call any other managed objects around, since we can’t be sure if they exist or not.

You should also be aware that objects having Finalize() method are cleaned by GC in two collections. When an object is allocated on managed heap, the runtime determines if it supports Finalize() method & if it does then it is marked as finalizable, & a pointer to it is stored on finalization queue. This queue helps, so that the objects must be finalized before they are removed from heap. When GC starts executing to free memory, then it checks each entry in finalization queue & copies the object off the heap to another managed structure named as freachable (finalization reachable). A separate thread is used by GC to invoke Finalize() on each object present on the freachable table at the next Garbage Collection.

 

   1: public class Wrapper : IDisposble
   2: {
   3:     // to determine if Dispose() method has already been called.
   4:     private bool disposed = false;
   5:  
   6:     // user should call on this method when they are finished with object.
   7:     public void Dispose()
   8:     {
   9:        // passing "true" signifies that the user triggered the cleanup.
  10:        // so dispose managed objects & clean unmanaged stuff too.
  11:        CleanAllStuff(true);
  12:        // suppress the finalization by GC, we don't need it now.
  13:        GC.SupressFinalize(this);
  14:     }
  15:  
  16:     private void CleanAllStuff(bool disposing)
  17:     {
  18:         // check if already been disposed.
  19:         if(!this.disposed)
  20:         {    
  21:             // if disposing == true, then clean up managed resources.
  22:             // i.e. called by user through Dispose() method.
  23:             if(disposing)
  24:             {
  25:                 // dispose managed resources here
  26:             }
  27:             // clean up unmanaged resources here.
  28:         }
  29:         disposed = true; // for future reference that object has been cleaned already.
  30:     }
  31:     
  32:     // Finalize() method, invoked by GC only.
  33:     ~Wrapper()
  34:     {
  35:         CleanAllStuff(false); // cleans only unmanaged stuff signified by passing "false".
  36:     }
  37: }

You can also check out some new GC class methods available in .NET 3.5 i.e. AddingMemoryPressure() & RemovingMemoryPressure() methods.

MSDN Sample available here.

kick it on DotNetKicks.com

About these ads
This entry was posted in Uncategorized. Bookmark the permalink.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s