Dear Shiv,
It is really gr8 article no doubt but just to understand quickly in depth i will request you to pleae provide some cases with the help of code snippets using all this stuff like finalizer, destructor etc.
I know that it will make your article big but i would love to read its next series. Do cover GC on different datatypes like on Static classes (please visit http://www.devnewsgroups.net/dotnetframework/t1387-memory-leak.aspx[^]) thread and http://blog.mbcharbonneau.com/2006/11/14/using-the-ping-class-in-net-20-without-memory-leaks/[^] to cover more scenarios in your next series, Please do include what to do what not to do and cases like if parent implements Idisposable and child too then what will be the functioning(yes the best way should be override parents implementation)
If an class uses 100% managed code, but it needs to implement iDisposable to clean up things like events, is it better style to use the normal iDisposable pattern and have the dispose routine do nothing when called from Finalize, or is it better to simply have a disposal routine that cleans up the events without bothering with the normal pattern? My impression is that it's common for classes that inherit from iDisposable classes to override Dispose(Boolean) and expect it to be called in case of a Finalize. Having a useless Finalize get registered seems silly, but not having a Finalize seems like it could be problematic.
I have to say that I'm very happy after reading your article, as it was very interesting and sufficiant detailed.
My small inputs:
Maybe you could add some informations about the 'using' statement for IDisposable objects.
The fact that you don't have to worry about exceptions (I mean that dispose is called also in this case), could be usable.
This could fit into 'What if developers forget to call Dispose?'.
'In other words if the client does not call the dispose function the destructor will take care of cleaning the unmanaged resources.'
I think this one, could be missinterpreted as, "don't worry if you forget to call dispose, the destructor will fix it."
The fact that the managed resources are not cleant propper, could lead to a situation that there are still references on the object and GC will not free this memory.
Maybe you could add some informations about the 'using' statement for IDisposable objects
Agreed i will update the article. You said right using statements takes care of these issues. One point to note we can only call one object in a using so...
Martin# wrote:
Maybe you have some time to look at my question about the topic, Is it possible to call the GarbageCollector of an other process?[^], which I asked some time ago in the C# forum.
I will have a look.
Visit my 500 videos on WCF,WPF,WWF,Silverlight,UML design patters @ http://www.questpond.com
I will not say I have failed 1000 times; I will say that I have discovered 1000 ways that can cause failure – Thomas Edison. Don't forget to click [Vote] / [Good Answer] on the post(s) that helped you.
There are a few inaccurate statements in the otherwise decent article.
Implementing destructor implicitly calls the finalize method.
The C# compiler translates (renames) the destructor into Finalize, there is no calling involved.
In your section on using Finalize/Destructor, you say
• If the object has a finalize method it moves those objects to the finalization queue.
• If the objects are reachable it’s moved to the ‘Freachable’ queue. If the objects are unreachable the memory is reclaimed.
The first statement is correct, but it is actually done at the time of object creation. The second statement is incorrect - if the object is reachable, it means someone is holding a reference to it, how can the CLR run its finalizer? The freachable queue is a queue to store references to objects that otherwise are not reachable, and the finalizer thread uses the queue to call finalize on those objects.
It's very difficult to write a Cleanup method as you suggested without knowing whether it's being called from Dispose or the finalizer - you should probably keep the disposed boolean parameter. As you might be knowing, the order of finalizers is not guaranteed, so you can't reliably cleanup other objects with finalizers from within a finalizer method call.
And finally,
• Do not have default constructors in your classes.
First thing i really appreciate your knowledge. No doubt you have indepth understanding of the way CLR works. Thanks for QCing my article , i have updated it and hope it will improve the quality of this article.
S. Senthil Kumar wrote:
Implementing destructor implicitly calls the finalize method.
Agreed i have updated my article. I meant the same thing but yes to make it to the point is much better.
S. Senthil Kumar wrote:
The first statement is correct, but it is actually done at the time of object creation
I will just check this again. What i read from the paper accordingly i had written.
S. Senthil Kumar wrote:
The freachable queue is a queue to store references to objects that otherwise are not reachable, and the finalizer thread uses the queue to call finalize on those objects.
Looks to be my english problem. I meant the same thing , if the objects are reachable it’s moved to the ‘Freachable’ queue ( in other words they can be accessed). Not sure if we are on the same page.
S. Senthil Kumar wrote:
keep the disposed boolean parameter
Already done, i wanted to make code more simplistic. But i agree it does not solve the problem. I agree to undetermestic nature of GC. I have updated the code
S. Senthil Kumar wrote:
Do not have default constructors in your classes
I mean to say empty constructors. Corrected it. I was at the last leg of the article so probably my empty brain was writing.
Visit my 500 videos on WCF,WPF,WWF,Silverlight,UML design patters @ http://www.questpond.com
S. Senthil Kumar wrote:
Do not have default constructors in your classes
I mean to say empty constructors. Corrected it. I was at the last leg of the article so probably my empty brain was writing.
Even with the correction I'm curious as of why an empty constructor is bad. My understand was that if you didn't provide one the compiler would anyway. So why would it have any impact on the GC and/or performance in general?
Empty constructor leads to moving the objects in Freachable queue. You can test it yourself create a class with empty constructors and then run it using CLR profiler many objects come in Gen 1 and 2. Which means your objects tend to stay more in memory.
Hope it helps.
Visit my 500 videos on WCF,WPF,WWF,Silverlight,UML design patters @ http://www.questpond.com
Again, it is documented through out the web that if no constructor is specified the compiler generates one for you. This would mean, in my view, that every object gets an empty constructor if no other is provided.
Now is the default empty constructor different from a user-defined empty constructor, I do not know. Maybe that's the case and it would explain your point of view on the subject.
In the end I don't think it makes much difference and I'm not ready to throw out my empty constructor