Click here to Skip to main content
11,584,612 members (68,541 online)
Click here to Skip to main content

Tagged as

Destructors vs Finalizers vs Dispose Pattern (Part 1)

, 17 Oct 2011 LGPL3 20.4K 4
Rate this:
Please Sign up or sign in to vote.
Dear Reader, I shall be talking about 3 topics by which we can clean up our mess created in our programs provided in C# .NET world. Bit History: I am sure you must be thinking now that “oh why re-inventing wheel?” or “Oh no not another same article which is available every where&#8

Dear Reader,

I shall be talking about 3 topics by which we can clean up our mess created in our programs provided in C# .NET world.

Bit History

I am sure you must be thinking now that “oh why re-inventing wheel?” or “Oh no not another same article which is available every where”. Honestly, these days i wanted to gain in depth knowledge on these topics and hence 3-4 days back i started reading many articles/blogs online in my free time. Upon reading so, i got many doubts which i started to ask myself. And i could not find answers for those self questions in one article/blog online. The information was so scattered, from Codeproject to Stackoverflow to CodeBetter to Codeguru and to couple of blogs.

Luckily after spending long time reading all the articles and trying to figure out the answers, i thought about writing a blog post on the my learn points. I shall be explaining in detail about these topics and in next couple of posts as and when i dig more and more about it. I would not claim that the content in this article is extraordinary because i might have missed out an article which could be good. Its just that i could not find the information easily. Have tried my best to give as much in depth information as possible. So kindly leave a comment if i have left out any thing or wrongly interpreted.

Let me start off then :)

Most of the C# .NET developers do get confused about these 3 topics and i must say here that these topics are really important as you gain higher programming experience in C# .NET world.

Note: In this article, i shall use Dtor. for Destructors and Ctor. for Constructors.

Introduction

We know in programming world, when ever we write some thing or consume some thing in programs we are occupying some space which is a memory here. So its always been our headache for decades in programming world to clean up our mess, the reason i call it as mess is that no matter how carefully we write our codes, still there are many areas we might leave our footprints back which we fail to clean up.

So traditionally all these years, most of our smart developers in various native languages viz C, C++, pascal, etc. Used to write alot of code to ensure that the memory is cleaned up neatly though it may not be the perfect ones but atleast we can say some cleaning up was better than making it more mess or left undone. It was not easy to write efficient code to clean up our used resources. So you can think how memory management was most complex and worried topic.

To avoid heavy complexity in managing memory, .NET technology came as a boon to developers who used to spend day and nights for memory management earlier. In .NET, memory management in cleaning up is often taken care off by our beloved GC, yes we all know that, so nothing new. But we often fail to convince ourselves that just because GC is there, it is yet not perfect. Because after all its again a bunch of codes written with some AI (Artificial intelligence) put into it in taking care of memory efficiently.

Even though GC does most of the jobs in reclaiming the memory back consumed by our code, still there are times we need to make sure we explicitly write code to release memory or help GC in its job. Hence to do this, C# .NET provided us 3 ways. So lets dig deep into each of those ways:

Destructors

This is not a feature which .NET supports but as a language C# has derived it from its predecessor C++ on which this language got evolved.

“Don’t get surprised if you read or hear from some body saying that .NET does not support destructors.”

Lets get in detail about the Dtor., then:

Like C++, the signature for Dtor. is similar in C# as well. So as per that C# like C++, Dtor. has the same name as the class prefixed with ~ char. Unlike Ctor., Dtor. can’t have any Access Modifiers associated with it nor you can make an explicit call. This is because, this is the last method which shall be called automatically by the run time before the resource is getting actually cleaned up or marked for garbage collection and hence no body else should be allowed to call explicitly, hence in IL a family (protected) modifier is assigned to this method to make it available for subclass, so that run time can track dependencies down the object hierarchy.

Now lets look a bit deeper into Dtor. here, upon disassembling, below compiled code in IL the Dtor. has been changed to some thing else as seen in the below image:

class MyClass
{
~MyClass() { }
}

As you can see from the above image, the IL shows that the Dtor. method has been converted to Finalize() method, well this is how the Run time identifies and calls it before really the object is garbage collected. Hence i said before that Dtor. is not a feature .NET is offering to us but rather C# is. This way this object can be marked for finalization. Don’t get worried about Finalization now, i shall explain later.

Lets see whats inside this strange named method called Finalize() AKA the Dtor.

As you can see from the above image, the compiler has introduced try-finally block into the Dtor. method.

The compiler is making sure that no user/developer written code in the Dtor. throws exception or go unhandled, reason being that in no case the memory reclaiming process should face any exception getting raised i.e the GC expects that any thing on which it is reclaiming the memory should not throw any exceptions.

A point worth mentioning here that, even though upon any exceptions generated on an instance, which GC is reclaiming memory by finalizing it. GC shall ignore those exceptions which got generated but on the same time it stops reclaiming memory. So its very uncertain that when the left incomplete job is taken up again will be completed.

Now there is one strange method being called inside finally block if you look at the IL picture. This is because it explicitly notifying the GC to garbage collect this object. I shall talk about Finalize() method later.

Lets ask ourselves the following questions about Dtor here and see if we can answer it convincingly to ourselves first.

  1. Why is that i see a Try-Catch/Finally block in the transformed Dtor method?

As already explained to make sure and to safe guard for a clean memory reclaim the compiler goes for a defensive coding and applies those blocks around your code.

  1. Can i fool the compiler by providing a custom Try-Catch/Finally block in the code?

Even though you can provide your custom blocks in your Dtor. code, still compiler ensures to apply this defensive blocks after compilation. This is because, even your catch/finally block which you have provided can still throw an exceptions.

  1. I see Object.Finalize() method being called in Finally. Why?

As already said, .NET only provides Finalizers to us and not Dtor. Dtor. feature is only by C# as language to facilitate Finalization. Although i shall talk more about Finalization later,  But to outline/answer this question, Object.Finalize() notifes the GC to garbage collect this object. But dont get relaxed reading this, doing finalization is not as easy as you think by GC. Hence in .NET GC is non-deterministic in nature. Hence it has to be called at the end of your object life cycle.

  1. Why can not i call directly this Finalize() method than using Dtor.?

Finalize() method is a protected method of Object class and C# does not allow you to call that method. Try it and you get a compiler error. So its all the trick Compiler is playing. The reason is that calling Finalize() is not recommended because it deals with alot complex operations internally. If allowed to call it explicitly in c#, a developer can call it when ever and at any time he/she wants. This will overload the whole system rather than improving it. Hence to avoid it, C# does ask you to use Dtor.

  1. Since i can’t call Finalize(), it should have been private but why it is protected?

The answer is simple, in .NET world every instance is a descendant of System.Object right? So, if Finalize() is private, then Finalization of that object is not possible and every child object has to provide its own implementation of Finalize if this was true. This adds alot of overhead. To reduce all this craziness, its made protected and C# does not allow you to use it explicitly.

A point worth mentioning here is that, even if you wish to see Object.Finalize() method via Visual studios Object Browser, then you can’t. You can only see ~Object() method which is kind of an alias for Object.Finalize() as you can see from below image:

The same holds true for System.object source code in visual studio too. Although the Objects Dtor. is also missing here as you can see from below image :

So if you are really curious like me to see if there’s really an Finalize() method in System.Object class, then disassembling is the only way as shown below:

That’s all dear reader, i do hope you have got enough insight about Dtor. feature in C#.NET.

In the next issue, i might continue on Finalizers and finally on Dispose pattern in depth if i could find some thing interesting about it from my experiments.

Thanks

P.S: Your valuable comments/Votes is well appreciated.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

Share

About the Author

zenwalker1985
Software Developer (Senior) Siemens
India India
A .net developer since 4+ years, wild, curious and adventurous nerd.

Loves Trekking/Hiking, animals and nature.

A FOSS/Linux maniac by default Wink | ;)

An MVP aspirant and loves blogging -> https://adventurouszen.wordpress.com/

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 1 Pin
rutav20-Mar-14 21:55
memberrutav20-Mar-14 21:55 
GeneralMy vote of 5 Pin
leo_ullas1-Sep-13 18:22
memberleo_ullas1-Sep-13 18:22 
QuestionC# disposers versus "real" disposers Pin
supercat917-Oct-11 12:40
membersupercat917-Oct-11 12:40 
AnswerRe: C# disposers versus "real" disposers Pin
zenwalker198517-Oct-11 16:12
memberzenwalker198517-Oct-11 16:12 
GeneralRe: C# disposers versus "real" disposers Pin
supercat918-Oct-11 9:56
membersupercat918-Oct-11 9:56 
GeneralRe: C# disposers versus "real" disposers Pin
zenwalker198518-Oct-11 16:10
memberzenwalker198518-Oct-11 16:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150707.1 | Last Updated 17 Oct 2011
Article Copyright 2011 by zenwalker1985
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid