Finalizers

1 min read

Purpose

In C#, a destructor (for example ~MyClass()) is syntactic sugar. The compiler translates it into an override of Object.Finalize(). Finalizers are meant as a fail-safe to release unmanaged resources if the developer forgets to call Dispose().

Non-deterministic execution

The GC calls finalizers at some point after an object becomes eligible for collection, but the exact timing is unpredictable. There is no guarantee when, or even whether, a finalizer will run, for example during an abrupt process termination.

Performance overhead

Objects with finalizers are more expensive for the GC to collect. They typically survive an initial collection and are placed on a finalization queue, which needs extra processing.

Best practice

Avoid implementing finalizers if possible. Proper use of the Dispose patternIDisposable and the Dispose patternHow to release the resources the garbage collector does not know about.Opens in a new tab, and of SafeHandle (a class designed to wrap unmanaged resource handles and provide robust finalization), can often remove the need for a custom finalizer. If Dispose() has been called and has done all the necessary cleanup, call GC.SuppressFinalize(this) to remove the object from the finalization queue, which improves collection performance.


Sources