by GeeksArray
This article describes implementing between dispose and finalize methods for cleaning up resources. It also explains the difference between dispose and finalize methods.
Finalize method is also called a destructor of the class. It is an ideal place to clean unmanaged resources implicitly like File Handlers, COM objects, Database connection that has referred by class. Finalize get called implicitly only once in the lifetime of the object and that is when the object becomes out of scope.
Although the garbage collector knows the lifetime of object which uses unmanaged objects, it does not know how to clean and release unmanaged objects. Garbage Collector calls this method at some point after there are no longer any valid references to the object. In inheritance chain Finalize method is called from the most-derived to the least-derived means the top most base class Finalize get called at last.
Writing clean up code in the destructor or finalize leads to GC visit twice and thus affecting the performance multifold times. You can get more tips on ASP.NET performance tips. Writing finalize makes your class expensive even it never gets called. So use it only when it is absolutely required to cleanup unmanaged code. Whenever you use the Finalize method also implement IDisposable.Dispose with GC.SuppressFinalize.
When you use destructor to release resources it implicitly calls Finalize method of the base class. A destructor and finalizer are basically interchangeable concepts.
For example, below is a declaration of a destructor for class Customer:
class Customer { ~Customer() // destructor { // cleanup statements... } }
The destructor of Customer class implicitly calls Finalize of the base class of the object. Therefore, the previous destructor code is implicitly translated to below code
protected override void Finalize() { try { // Cleanup statements... } finally { base.Finalize(); } }
Cleaning up resources through Finalize or Destructor is nondeterministic because GC has its own algorithm to reclaim memory. The CLR gives a way to implement deterministic cleaning of resources using IDisposable interface, Dispose of method to allow the object to execute it explicitly.
The issue with nondeterministic finalization is, it happens at an undetermined point mostly when memory is not enough to work. So the objects like DB connection or File handlers are unnecessary alive in memory.
For cleaning up a resources in a deterministic way you have IDisposable.Dispose method. In each class when there is a reference to any unmanaged resource you should give users ability to clean resources explicitly by providing the Dispose method.
public class Customer : IDisposable { private StringReader _reader; // to detect redundant calls private bool disposed = false; public Customer() { this._reader = new StringReader(); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { if (reader != null) { this._reader.Dispose(); } } disposed = true; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } }
Finalize | Dispose |
It is a method of Object class. |
It is implemented as part of the IDisposable interface. |
Finalize is responsible for cleaning of the unmanaged resources like Files, DB connections, COM etc. held by object before that the object is destroyed. |
Dispose can release unmanaged resources like Files, DB connections, COM etc. at any time. |
It is called by Garbage Collector and cannot be called by User. |
It is the users' responsibility to call the Dispose method explicitly. |
It has performance cost as GC has to visit Finalize twice. |
No performance cost. Rather it helps to release resources as soon as possible. |
Recommended it when you have unmanaged resources, and want to make sure about these resources to be freed when the Garbage collection happens. |
Recommended it when your class users gets facility to free resources. |