Introduction
We have been using the Dispose method for disposing of objects. NET. For the same purpose, we may also use the Finalize method. In this article, I will try to explain what the Dispose and the Finalize methods are where to use the Finalize, and where to use the Dispose. I will also try to explain the difference between them.
Dispose
The garbage collector (GC) plays the main and important role in .NET for memory management so the programmer can focus on the application functionality. The garbage collector is responsible for releasing the memory (objects) that are not being used by the application. But GC has the limitation that, it can reclaim or release only memory that is used by managed resources. There are a couple of resources that GC is not able to release as it doesn't have information, on how to claim memory from those resources like File handlers, window handlers, network sockets, database connections, etc. If your application has these resources then it's the program's responsibility to release unmanaged resources. For example, if we open a file in our program and not close it after processing then that file will not be available for other operations or if it is being used by other applications they can not open or modify that file. For this purpose, the FileStream class provides the Dispose method. We must call this method after file processing is finished. Otherwise, it will be through exception Access Denied or the file is being used by another program.
Close Vs Dispose
Some objects expose Close and Dispose two methods. For Stream classes, both serve the same purpose. Dispose method calls the Close method inside.
void Dispose()
{
this.Close();
}
Here question arises, why do we need the Dispose method in Stream? Having the Dispose method will enable you to write the below code and implicitly call the dispose method and ultimately call the Close method.
using(FileStream file = new FileStream("path", FileMode.Open, FileAccess.Read))
{
// Do something with file
}
But for some classes, both methods behave slightly differently. For example Connection class. If the Close method is called then it will disconnect with the database and release all resources being used by the connection object and the Open method will reconnect it again with the database without reinitializing the connection object. However, the method completely releases the connection object and cannot be reopened just by calling the Open method. We will have to re-initialize the Connection object.
Creating Dispose
To implement the Dispose method for your custom class, you need to implement an IDisposable interface. IDisposable interface exposes the Dispose method where code to release unmanaged resources will be written.
Finalize
Finalize method also called destructor to the class. Finalize method can not be called explicitly in the code. Only the Garbage collector can call the the Finalize when object becomes inaccessible. The finalized method cannot be implemented directly it can only be implemented via declaring a destructor. The following class illustrates, how to declare a destructor. It is recommended that implement the Finalize and Dispose methods together if you need to implement the Finalize method. After compilation destructor becomes the finalized method.
public class MyClass : IDisposable
{
// Constructor
public MyClass()
{
// Initialization
}
// Destructor also called Finalize
~MyClass()
{
this.Dispose();
}
public void Dispose()
{
// Write code to release unmanaged resource
}
}
Using Finalize
Now the question is When to implement Finalize? There may be any unmanaged resource for example file stream declared at class level. We may not know what stage or which step should be appropriate to close the file. This object is being used in many places in the application. So in this scenario Finalize can be an appropriate location where unmanaged resources can be released. It means, cleaning the memory acquired by the unmanaged resource as soon as the object is inaccessible to the application.
Finalize is a bit expensive to use. It doesn't clean the memory immediately. When the application runs, the Garbage collector maintains a separate queue/array when it adds all objects that have been finalized and implemented. In other term, GC knows which object has Finalize implemented. When the object is ready to claim memory, the Garbage Collector calls the finalize method for that object and removes it from the collection. In this process, it just cleans the memory that is used by unmanaged resources. Memory used by managed resources is still in the heap as an inaccessible reference. That memory is released, whenever Garbage Collector runs next time. Due to the finalized method, GC will not clear the entire memory associated with an object in the first attempt.
Conclusion
It is always recommended that one should not implement the Finalize method until it is extremely necessary. Priority should always be to implement the Dispose method and clean unmanaged as soon as possible when processing finishes.
Junaid AnsariPosted Feb 6, 2022, 7:31 AM
You had me at Now question is, When to implement Finalize? There may be any unmanaged resource for example file stream declared at class level. We may not be knowing what stage or which step should be appropriate to close the file. This object is being use at many places in the application. So in this scenario Finalize can be appropriate location where unmanaged resource can be released. It means, clean the memory acquired by the unmanaged resource as soon as object is inaccessible to application.
Sasi RekhaPosted Dec 18, 2018, 6:28 AM
I was searching for what happens if declare dispose() in destructor ,finally i got answer,its really great
Siddhant ShivaniPosted May 27, 2018, 4:24 AM
Here, The reason given for finalize to be expensive is "it just clean the memory that is used by unmanaged resource. Memory used by managed resource still in heap as inaccessible reference.". Actually we don't clear managed resource from finalize because it will automatically be removed by the GC because when finalize method is called all the references to the object are out of scope. So, it is not recommended to remove the managed resources manually. Otherwise, From Dispose and finalize both we call the same Dispose(bool disposing) method. It is on us whether we want to clear the managed resource from finalized metod or not.But, It is not recommended to clear the managed resource from finalize. You can check the implementation of these methods in any website or book. The reason for finalize to be expensive is it waits till all the reference of object goes out of scope then only it cleans the memory. But for the dispose method it is in our control when we want to release the resources. we can call the dispose method as early as possible. It is always recommended to implement finalize method as well along with dispose If in any case we forgot to call the dispose method. Then finalize method saves us from memory leak.
kalu singh raoPosted Jul 8, 2016, 1:21 AM
Nice...
AmalaratchagarPosted Jun 14, 2016, 11:29 AM
Good to read these kind of basics articles again after many years..
Pankaj Kumar ChoudharyPosted May 20, 2016, 5:09 AM
Nice Explanation.........
Manoranjan BeheraPosted Apr 29, 2016, 8:07 AM
So nice decription
Shridhar SharmaPosted Oct 16, 2015, 1:01 PM
nice share
Kamlesh BhorPosted Oct 16, 2015, 8:10 AM
Nice...
Humayun Kabir MamunPosted Oct 16, 2015, 8:04 AM
Nice...
Nilesh JadavPosted Oct 16, 2015, 7:20 AM
Good Explain
Mukesh KumarPosted Oct 16, 2015, 7:04 AM
I was so confuse between both ... but now i am clear my doubts thanks
Rajeesh MenothPosted Oct 16, 2015, 6:49 AM
Nice One!
Harshad PansuriyaPosted Oct 16, 2015, 6:30 AM
Nice one
Aarya MorchePosted Aug 20, 2013, 11:39 PM
one question ..... Garbage collector maintains a separate queue when it adds all object which has finalized implemented , but if those objects having some internal chain of references then still it is clean the memory for those objects?
Nitya SharmaPosted Mar 28, 2013, 3:38 PM
when object becomes out of scope or object no longer in use, memory occupied by that object doesn't get released immediately. It gets release whenever GC runs. We can't control when GC runs, it runs with some interval or whenever more memory requires by application.
udit guptaeditedPosted Jul 26, 2012, 11:57 PMEdited Jul 27, 2012, 12:00 AM
Hey one question.. since finalize is implemented in C# using deconstructer and we can create one of our own which gets called soon after the object is no longer in use, so does that mean we are accessing finalize()? actually this is in regards to the statement that we can not control when finalize gets called
udit guptaPosted Jul 26, 2012, 11:57 PM
Nice Article
RaananPosted Nov 25, 2011, 4:39 PM
:)
Dinesh BeniwaleditedPosted Nov 17, 2011, 3:12 AMEdited Nov 17, 2011, 3:12 AM
Good start, Welcome to the Mindcracker Community Nitya.