The .NET Garbage Collector does almost all the cleanup 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 of needing two rounds to clear the objects.
Example
Let’s say there are three objects, A, B, and C.
C is overridden 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, it 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 do we trigger it automatically if we forget to call it?
Solution
Call the Dispose method in the Finalize method and suppress the Finalize method using GC.SuppressFinalize.
The following is a 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 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.