The .NET Garbage Collector does almost all the clean up for your objects.
There are two types of resources where the Garbage Collector clears memory.
- Managed resources
These resources are cleaned up automatically.
- Unmanaged resources
These are objects like files, Windows handles, Windows API created objects, Database connection objects, COM objects, and so on.
To clean up these types of objects we need to use Object.Finalize.
But Object.Finalize has the problem that it needs two rounds to clear the objects.
Example
Let’s say there are three objects, A, B and C.
C is overriden with Finalize and A and C without Finalize.
In the first round it will clean up A and C and due to the marked C override with Finalize it will be moved to the Finalize Queue.
After clean up it will be moved to the second round to clean up the Finalize Queue.
There are two rounds for clearing memory.
So this is not the best practice to use Finalize, instead we can use Dispose.
Dispose
Dispose calls a method IDispose. It defines a method to release allocated resources.
The Dispose method's responsibility is to clean up allocated resources for unmanaged objects.
But how to trigger it automatically; if we forget to call it?
Solution
Call the Dispose method in the Finalize method, suppress the finalize method using GC.SuppressFinalize.
The following is sample code to do this.
public class CleanClass : IDisposable
{
public void Dispose()
{
GC.SuppressFinalize(this);
}
protected override void Finalize()
{
Dispose();
}
} Instead of using a try/catch statement we can call this in a using statement.
Conclusion
In this article we saw that any unmanaged code will not be cleaned up by default.
We need to use Object.Finalize; but the Finalize method requires two rounds to clean up unmanaged code and that is not a best practice so we can use the Dispose method by calling the interface IDispose method in Finalize so it will be automatically called.