I got the following question recently.
What is the difference between Dispose and
SupressFinalize in garbage collection?”
The problem with this question is it assumes Dispose and SupressFinalize have similarities, which I’m sure is not what is being asked here. So let’s rephrase it in terms that make sense.
I see three methods available to me in .NET that all seem to have something to do with garbage collection. Can you explain what Dispose, Finalize, and SupressFinalize do and why I could use or call each one in my code?”
Now, that’s something we can answer.
A Brief History of Memory Management
Before we answer the question, we need to review how memory management works in .NET compared to historical languages such as C/C++.
In the old days, if an application allocated memory on the heap (generally done with the “new” keyword in CSharp) the application was also responsible for releasing the memory. In languages such as C++, this was done with the “delete” keyword which triggered a call to a special method called a destructor. If the object was holding on to memory or other resources, it was the destructor’s job to release those resources.
In .NET memory is deallocated for us using garbage collection. We no longer call the destructor using anything like a delete keyword and the deallocation process happens at some point in time that is after the memory goes out of scope. This might be immediately after the object goes out of scope or it could be hours or days.
Generally, this is not a problem, but what about an object that is holding on to additional resources that need to be freed up right away?
For that we have the Dispose() method.
Dispose is the new destructor.
While we don’t need a destructor to handle our memory, we do need something to release resources. This is why the IDisposable interface was created with one method that needs to be implemented called Dispose().
If your class allocates resources that need to be freed up that aren’t memory, you should implement the IDisposable interface on that class and implement the Dispose() method. Inside that method, you would release any resources that the class may have created and not freed.
Dispose() will then automatically get called by Finalize()
When the garbage collector starts releasing memory, one of the things it will do is that it will go through your code and call Finalize() on each of the objects. Finalize() will then call any dispose methods that are available.
This is done to protect the programmer from himself, not because it is expected. Remember I said the memory will get freed up at some indeterminate point in the future but the Dispose() method was created so we could free up the resources right away?
What we really want to do is call Dispose() ourselves. We call Dispose from our own code. Finalize() only exists so that Dispose() will get called if we don’t.
And that’s where SupressFinalize() fits in.
If my code calls Dispose() then there is no reason for the Finalizer to run at all. Without SupressFinalize() we would need to set a flag in our class indicating that Dispose() had already been called so that when Finalize() called it, we didn’t re-run the clean up code.
With SupressFinalize() we can just call SuppressFinalize() from within Dispose() and that will tell .NET to not run the Finalize method when it gets to our object.
Your call to SupressFinalize() should almost always look like
Other post in Advanced CSharp
- Two Interfaces. Same Method. Two meanings. - September 29th, 2008
- Readonly variables in CSharp? Really?! - October 29th, 2008
- Dispose with Using - November 10th, 2008
- Delegates in .NET - December 4th, 2008
- Using Sealed in CSharp - December 8th, 2008
- CSharp checked and unchecked - December 11th, 2008
- Unsafe Mode in C# - December 15th, 2008
- Volatile variables and CSharp threads - December 22nd, 2008
- What is the global keyword in CSharp? - December 29th, 2008
- CSharp fixed keyword - January 5th, 2009
- using - There's more there than you are using - February 2nd, 2009
- Removing Warnings from CSharp Compile Cycle - March 10th, 2009
- Just say “No!” to C# Regions? Really?! - April 16th, 2009
- C# “” better than string.Empty? - April 20th, 2009
- .Net String Pool – Not Just For The Compiler - April 22nd, 2009
- CSharp ?? Operator - May 18th, 2009
- Using VB.NET From CSharp - July 1st, 2009
- What is .NET’s Object.GetHashCode() Used For? - August 5th, 2009
- ASP.NET Substitution Control - October 22nd, 2009
- Transaction Tracking Typed Datasets Using SqlTransaction - July 20th, 2010
- CSharp's Property Shortcuts - July 17th, 2012
- && vs & and | vs ||... What's the difference? - August 21st, 2012
- Advanced CSharp - yield - November 27th, 2012
- Making values nullable - December 18th, 2012
- Stackalloc in CSharp - January 22nd, 2013
- Dispose, Finalize and SuppressFinalize - June 12th, 2013
- CSharp Numeric Overflows - July 3rd, 2014
- CSharp IDisposable Confusion - July 17th, 2014
- Why Get Certified? - July 24th, 2014
- Running Selenium In Parallel With Any .NET Unit Testing Tool - July 31st, 2014
- Browser Automation in .NET w/ Chromium - July 9th, 2015
- CefSharp Offscreen [Why do I have so many instances of Chromium?] - October 1st, 2015