Finalize vs Dispose in C#

Advanced

2019-03-04

What is Finalize method ?

In object oriented languages that uses garbage-collection, a finalizer is a special kind of method that does finalization and clean up of object during object destruction and before it's being de allocated. 

Finalize method is called by the garbage collector when it reclaims the object and it's up to the GC to when it will be executed. it has a performance effect and you should be careful when using it.

  • Finalize should release unmanaged code only.
  • Never allocate memory in finalize.
  • No guarantee when it will be executed

Finalize methods is very discouraged , and "Dispose" should be used instead.

What is Finalization queue in C# ?

When a new object is created, the memory is allocated in the managed heap. If newly created object have a Finalize() method or a destructor then a pointer pointing to that object is put into the finalization queue. Basically, finalization queue is an internal data structure that is controlled and managed by the GC. Hence each pointer in finalization queue points to an object that have its Finalize method call before the memory is reclaimed.


What is Destructor ?

A Destructor is a method that is called automatically when the object is destroyed, dynamically allocated or leaves it's scope.

In deterministic object life time languages like C++ the object will have a destructor, while in non-deterministic object life time languages that uses garbage collection like C# objects will have a finalizer.

What is Dispose ?

It's a design pattern where an object implements an IDispose interface, this object usually allocates unmanaged resources like , file streams, network sockets ... etc through a "dispose()" method.

these resources need to be cleaned and de-allocated manually, as the GC doesn't have a deterministic time to free these unused resources, so the dispose function  needs to be called explicitly.

Example using Dispose in C#




Difference between Finalize and Dispose ?

  • When the compiler generates code for the constructor, it generates code for base constructor, and the same happens for destructor.
  • Finalize methods are different, the compiler doesn't know about finalize, so it won't generate code to call base finalize method, you have to call it explicitly as the last step in child finalize method.
  • Dispose is called from code, it can suppress finalize.