Cleaning the Resources: Finalize vs Dispose

In the programming world, we know that whatever object is constructed, the same object should be destructed as well, after use. So I would like to talk about the Destructor (DCtor) that is available in C#.

life of an object

The preceding figure shows the life of an object.

When we create a class, it allocates the memory space use new keyword. This will call the constructor of a class to initialize the properties/variables. Likewise the figure shows how a person is called to construct the building. You can consider a person as a constructor and the tool in his hand as new.

The 2 persons in the second figure are properties or methods that are used in the application once the building is constructed. After use, when the building gets older or all people move from the building it is like making the building unused (object). So this unused building (object) that is occupying unnecessary space should be destroyed, so that it can be replaced with a new building (object). Here comes the bulldozer or a tanker to destroy the unused object that we will consider as the Garbage Collector. This Garbage Collector destroys the building or an object and frees the space for other building (object) allocation.

This article is not intended to explain how the life of an object is in the real world, but to explain how a Destructor (Finalize) and how Dispose works.

  1. public class Building  
  2. {  
  3.     public int CountOfFlats { getset; }  
  4.     public void CleanStairs()  
  5.     {   
  6.        //Code here  
  7.     }  
  8.     public Building()  
  9.     {  
  10.        Console.WriteLine("Building constructor called");  
  11.     }  
  12.     ~Building()  
  13.     {  
  14.        Console.WriteLine("Descructor called");  
  15.     }  

Finalize

In C#, when you create a class, we can do the following 3 things:

  • Create a constructor (either default or parameterized)
  • Create variables, properties, methods
  • Create Destructor (~)

When we write the destructor for a class, it will not have any access specifier attached with it and the name of the Destructor remains the same as the class name. This is the last thing to be called automatically once the class goes out of scope.

The CLR provides support for automatic memory management. The only problem is with unmanaged resources that is done by us.

In C#, a Destructor internally calls the Finalize method that actually marks the object for finalization where the Garbage Collector releases a specific object that has no longer valid references. But this release of memory done by the Garbage Collector executes after some interval by the CLR that is not known to us.

It is bad practice to create a destructor, because as said before, it will check the class for an available destructor and move the object in a generation 1 or generation 2 heap for finalization and wait for the Garbage Collector to execute and release the memory, it will not release it immediately.

Keeping the object in a Generation 1 or Generation 2 heap will degrade the performance of an application since they are considered to be long-lived objects. So to avoid this problem the .NET Framework provides a Dispose method to release the unmanaged resources as soon as they are not needed.

Dispose

This method can be created by any class implementing an IDisposable interface. In this method we will be writing the code for cleaning the resources of an object. It is very important and we can free up all the unmanaged resources in this method like database connection, files and so on.

Here, we don't need to have a destructor method but in case we have already written a Destructor method you should call the GC.SuppressFinalize method within this Dispose as shown below for requesting the CLR not to call the Finalize method, the garbage collection for this object is already done.

How to implement the Dispose method

  1. public class Building : IDisposable  
  2. {  
  3.     public int CountOfFlats { getset; }  
  4.     public void CleanStairs()  
  5.     {   
  6.         //Code here  
  7.     }  
  8.     public Building()  
  9.     {  
  10.       Console.WriteLine("Building constructor called");  
  11.     }  
  12.   
  13.     ~Building()  
  14.     {  
  15.        Console.WriteLine("Descructor called");  
  16.     }  
  17.   
  18.     public void Dispose()  
  19.     {  
  20.        //Clean the unmanaged code  
  21.        GC.SuppressFinalize(true);  
  22.     }  

Conclusion

I hope you liked this small article that is focusing on Destructor vs Dispose methods for cleaning the resources from memory. Please leave your comments whether it's good or bad.

Reference

Difference between Destructor, Dispose and Finalize methods