IDisposable and managed resources [duplicate] - c#

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Proper use of the IDisposable interface
I have a class that has both managed and unmanaged resources. I am using IDisposable to release un-managed resources. Should I release managed resources in the dispose method? Or I can leave it to GC to release managed resources?

If you have a look at the following documentation you will find the line:
Free any disposable resources a type owns in its Dispose method.
So in your dispose method you should dispose of managed resources that also implement IDisposable. If an object doesn't implement this, you don't have to dispose of it.

I would suggest that classes with finalizers (the C# compiler generates finalizers for any classes with destructors) should avoid holding references to any objects that won't be used in finalization. With relatively few exceptions, classes which hold resources that are encapsulated in objects should avoid holding resources that are not so encapsulated. Instead, those resources should be encapsulated into their own objects, so they can be held along with the other resource-containing objects.
Once that has been taken care of, the proper behavior for any class which owns resources that are encapsulated in other objects is generally to call Dispose on all such resources within its own Dispose method, and not to implement a finalizer (and--for C#--not to have a destructor, which would cause the compiler to generate a finalizer). If the finalizer runs on an object which holds other finalizable objects, each of those objects will usually be in one of three states:
The finalizer on that other object will have already run, in which case it's not necessary to do anything to clean it up.
The finalizer on that other object will be scheduled to run, in which case it's probably not necessary to do anything to clean it up.
Other strong references may exist to that other object, in which case it shouldn't be cleaned up yet.
Only in the second case would there be any reason to think about doing any cleanup on the other object.
Note, btw, that the garbage collector should almost never be relied upon to do anything other than free up memory directly consumed by object instances. Deterministic disposal is almost always much better. The only times one should ever deliberately use the garbage collector to clean up resources is when one is going to be creating relatively-low-cost resources which are known to clean themselves up effectively when garbage-collected, and the instances will be widely-enough shared that finding out when the last one leaves scope would otherwise be impractical. Although there is sometimes good justification for abandoning disposable objects, abandoning disposable objects without justification is always a mistake (if it's appropriate to abandon disposable objects, it's appropriate to justify one's reasons for doing so).

Related

In C# does (new Obj()).foo() dispose of Obj when the parenthesis scope is exited?

I am happy using IDisposable and using blocks but often I find myself writing (new Obj()).Foo(); to avoid the extra instantiation code and naming etc. Does this instance hang in memory until the end of the function scope or is it disposed of directly after the enclosing parenthesis is exited...? Is there an alternative I am missing? An equivalent to implementing IDisposable for concrete objects that I want to use once and throw away?
IDisposable is not related whit when the memory allocated for the object is released. In both cases the memory is released when the Garbage Collector decides to release it.
IDisposable is used for objects that need to execute some action in order to release the resources it allocates outside them. For example if the objects open a Database connection, you must release it as soon as you don't need it anymore.
So IDisposable gives you one thing:
A way to release the resources as soon as you want, by calling the Dispose() method or using the using clause
So it's ok to do:
new Obj()).Foo();
And has no sense to make Obj implements IDisposable if it does not uses any resource that must be deallocated.
If an object implements IDisposable, it is imperative that you Dispose() the object in your own code, either explicitly (and within a try/finally construct, too!) or with the using syntax, and do not simply let the reference(s) fall out of scope.
EDIT: I feel like I used an awful lot of words to get around to explaining the most important aspect of all this, which is that the only reason an object should implement IDisposable is if it holds handles to other objects that are unmanaged (the CLR doesn't know about them) or scarce (due to resources/cost/licensing/etc.). So if an object implements IDisposable, you MUST call Dispose() YOURSELF, as soon as possible. The CLR will not do it for you. And if you implement IDisposable on your own classes, you need to be implementing a finalizer on them, too.
Simply letting a reference fall out of scope does not cause the GC to run immediately, and you have no guarantees whatsoever that a GC is going to occur any time soon. You can explicitly trigger a GC with code, but that is typically going to hurt overall performance more than help it.
If there is not much memory pressure, for instance, the CLR may wait a long time before running the GC. There just isn't a pressing need for it to run in a situation where there is light or zero contention for resources. If it ran too often, it would impact the performance of your applications negatively
The GC does not call Dispose(). The GC calls an object's finalizer if it has one. The finalizer is a special method using syntax similar to a C++ destructor, but which really is not a destructor in that sense.
So if an object implements IDisposable, but does not implement a finalizer, the GC will never release that object's resources. The object will cause both memory leaks and unresolvable resource contention.
Nor does calling Dispose() from your own code trigger a GC.
The finalizer is a last-ditch backup mechanism to try to ensure that a class holding scarce or expensive resources does eventually let go of them even if consumers of the class fail to explicitly release those resources.
IDisposable is really just a common convention, implemented with a handy well-known interface contract, to let callers generically request that any class holding scarce resources release those resources immediately.
The standard pattern is that the finalizer calls the Dispose() method (actually, it typically calls Dispose(false) and I'm intentionally ignoring that detail). The Dispose() method will release all the scarce resources, then it can call GC.SuppressFinalize() so that the GC can free the object's memory more quickly when it gets around to running.
The old tried and true "acquire late/release early" semantics apply here.
You should read up on how the GC uses multiple passes or "generations" to clean up objects with finalizers.
The GC can get rid of regular objects (objects where all the resources are managed by the CLR) in one pass. If there are no in-scope references to an object, the GC can basically just delete it.
But if an object has a finalizer (and GC.SuppressFinalize() has not been called), the GC uses at least 2 passes or generations to release the object. In the first generation, it marks the object for finalization. In the second generation (which happens the next time the GC runs), it actually calls the finalizer, and at that point the object is finally eligible to have its memory released.
The scarce/expensive resources we're talking about are typically things like network sockets, file handles, database or other server connections which may be limited or expensive or resource-intensive or all three, etc. This is also true of virtually all "unmanaged" (non .NET CLR) resources, including things like Win32 window handles, file handles, network sockets and so on. Such resources require deterministic cleanup. You need to let go of them as quick as you can, but the CLR is going to take its sweet time getting around to cleaning this stuff up. You have to do it yourself.
But if your class isn't using any of these types of scarce/expensive/"unmanaged" resources, then there is probably no reason to implement IDisposable on it at all.

Garbage Collection best practice in .net

What is the difference between System.GC.Collect and Dispose()?
Aren't they used for the same purpose, and when should each be used; what is the best practice?
Best practice is to never need to call GC.Collect, and to call Dispose on all IDisposable objects when you're done with them.
The purpose of GC.Collect is to to tell the Garbage collector that there are some objects in the memory that can be collected and it is the right time to collect. Though, as a rule of thumb you should leave that to GC itself. It is designed to do this job.
If there are some resources in your object that you think GC won't take care of. You should implement Dispose and take care of them yourself. You need to call Dispose Explicitly to dispose the resources you want. And if you are implementing IDisposable than you can also do that by the Using statement.
System.GC.Collect is called when all objects which are there in memory are to be collected by the Garbage Collector. Objects which are referenced in managed code are not considered for Garbage collection. This method is used to force the system to reclaim the available memory.
Dispose() is not part of GC but as better practice you can use this. It should only be used for objects which uses unmanaged resources like FileStream etc. It should release all the resources that it owns. When you know that certain resources will not be released by GC then you can use the Dispose() method.
The using statement ensures the correct use of IDisposable objects.
On a side note: The GC does not call Dispose, it calls the finalizer(which you should call from Dispose(false))
Also, to make ensure that resources are always released appropriately, a Dispose method should be callable multiple times without throwing an exception.
MSDN says:
"It is possible to force garbage collection by calling Collect, but
most of the time, this should be avoided because it may create
performance issues. "
Check this blog:-
GC.Collect() asks the system to perform a collection "now". You
shouldn't mess with this; the system usually has a much better idea
than you do of when collection is necessary.
So is the best practice:
You can use the using block or as you mentioned use the Dispose method.
Why should you use IDisposable and Dispose?
MSDN says
In many cases it is possible for objects that would otherwise always
need to be finalized to avoid that cost by implementing the
IDisposable interface. This interface provides an alternative method
for reclaiming resources whose lifetime is well known to the
programmer, and that actually happens quite a bit. Of course it's
better still if your objects simply use only memory and therefore
require no finalization or disposing at all; but if finalization is
necessary and there are many cases where explicit management of your
objects is easy and practical, then implementing the IDisposable
interface is a great way to avoid, or at least reduce, finalization
costs.
Also check this article on Improve garbage collector performance using finalize/dispose pattern

More information on how C# Dispose works

In trying to understand the IDisposable i have a few questions that most answers haven't explicitly stated.
If we call dispose on an object, does that dispose the object at that time or just class members that we would like to clean up, and the whole object would be destroyed later by the GC.
After we suppress the finalizer in the dispose method, will the GC still clean up all the class members we didn't clean up in the dispose?
An object will be garbage collected once all references to it are gone, in a non-deterministic way. Garbage collection
from MSDN : Garabge collection fundamentals
Garbage collection occurs when one of the following conditions is
true:
The system has low physical memory.
The memory that is used by allocated objects on the managed heap
surpasses an acceptable threshold. This means that a threshold of
acceptable memory usage has been exceeded on the managed heap. This
threshold is continuously adjusted as the process runs.
The GC.Collect method is called. In almost all cases, you do not have
to call this method, because the garbage collector runs continuously.
This method is primarily used for unique situations and testing.
Garabge collection when to use
Understanding Object life cycle
First things first, there is a ton of duplicate questions here on this topic. If truly none other answer explicitly answers your question, here they are, but I expect this to be closed as a duplicate.
First, Dispose is just a method, an ordinary method. It does not deal with Garbage Collection at all.
So what does Dispose do? It should be used to clean up unmanaged resources, such as file handles, window handles, etc. Things that the .NET garbage collector does not know about.
So to answer question 1: "Yes", when you call Dispose on an object, it is disposed there and then. There is no mark set on the class to indicate cleanup later on.
Since Dispose does not deal with Garbage Collection, you can easily keep a reference to the object after disposing it, and it will not be garbage collected. Garbage collection only occurs when there are no more references to the object. This can happen even if you have not called Dispose on the object, but it will not happen because you call Dispose on the object.
Second question: When GC collects the object after it has been through the finalizer cycle, then GC will clean up the object + any object it refers to that no longer has any references left (besided the one from your object). This happens at some point, and not necessarily all at once either.
Suppressing the finalizer is just making sure GC does not do more work than necessary, by saying that "when you find this object and determine that it is eligible for collection, then just go ahead and collect it, I have taken care of the 'finalization' cleanup so you don't have to".
Firstly and most important you need to understand that disposing an object and garbage collecting an object are completely different things - make sure that you don't confuse the two!
If we call dispose on an object the only thing that happens is that the Dispose method gets called. It might be that the Dispose method then goes on to call GC.SuppressFinalize, but then again it might not do anything at all - its completely up to the implementation.
When we call GC.SuppressFinalize the only thing that happens is that it requests that the GC not call the objects finalizer when the object is collected (almost as if the object didn't have a finalizer in the first place).
As it happens a common pattern is for objects which have a finalizer to also implement IDisposable so that unmanaged resources can be cleaned up deterministicly - if this happens then there is no need for the GC to call the finalizer as the work that would have been done in the finalizer has already been performed when we called Dispose - calling GC.SuppressFinalize is just a friendly hint to the GC that it doesn't really need to call the finalizer after all.
1) When you call dispose on an object, all that happens is that the code in its Dispose() method is run. This code may of course call Dispose() for one or more of its fields, but it's not required to.
It may also call the base class' Dispose(true), if any (via base.Dispose()), but that is using the Dispose Idiom; Dispose(bool) is NOT part of the IDisposable interface.
2) The finalizer is suppressed only for the specific object for which SuppressFinalize() was called. It won't affect any other objects (including any held by fields of the object for which SuppressFinalize() was called).

IDisposable and Destructors in abstract base class

I have an abstract base class which implements IDisposable and the full bool disposed = false, Dispose(), and Dispose(bool) pattern except for the destructor. The base class implements IDisposable since many of its derived classes need to release unmanaged resources. However, I heard that classes with destructors are expensive and thus would make the derived classes that do not have unmanaged resources unnecessarily expensive, had I included the destructor. I'm confused on this matter. Should I or should I not include the destructor and why? Thanks.
You only need to include a destructor/finalizer if you are implementing an entirely new kind of unmanaged resource. So if you're just wrapping or inheriting an existing database connection type, socket type, gdi resource, etc, then you do not need a destructor. The destructor in the original type will take care of finally releasing that resource for you. But if you are implementing something like the ADO.Net provider objects for an entirely new kind of database from scratch, then you would want to implement a destructor for your connection type, so that it can release it's connection when it is finally collected.
Ideally the Dispose pattern relies on the finalizer as well to be complete. The reason is to be sure that the unmanaged resources will be cleaned up. The trick here is that in the Dispose method you also should have the following call: GC.SuppressFinalize(this), which instructs the garbage collector not to treat the instance in a special way, which will keep you from the overhead of finalization. So if the user works with the object correctly disposing it every time (like wrapping in every usage in a using block) then the finalizer won't be called thus not affecting the performance at all.
I heard that classes with destructors are expensive
Classes with finalizers or implementations of IDisposable are not more expensive than those without. However, a class implementing IDisposable is telling the caller that they need to be kept track of and cleaned up when no longer needed. That is additional work for the caller but the cost of not doing so is a resource leak, at least until the class is garbage collected.
In short, if your class does not use any resources that need to be cleaned up, usually in the form of fields that also implement IDisposable, you do not need a finalizer.
The only classes which should override Finalize for the purpose of cleanup are those which either derive directly from Object and expect to clean up their own resources, or things like SafeHandle, whose purpose is to manage resource cleanup. Otherwise, if a derived would have unmanaged resources that need to be cleaned up in Finalize but the base class would not, the proper approach is usually to encapsulate each separate resource in its own finalizable object. Objects which have finalizers should avoid holding strong references to any objects which are not needed for finalization, since all objects to which they hold references, as well as all objects to which any of those object hold references, etc. will be kept alive for an extra garbage-collection generation. If an object George which holds links to many other objects holds a reference to a finalizable object which does not hold a strong back-link, and George is abandoned, the finalizable object will need to be kept around for an extra GC generation but George and the other objects to which it holds direct and indirect references will not. By contrast if George itself implemented Finalize, then it and every object to which it holds a direct or indirect reference would have to be kept around.
Further, finalization can sometimes cause some rare but hard-to-track-down Hindenbugs if the last use of a large finalizable object is actually a use of one of its resources. Code which uses resources that can be cleaned up via Finalize must make sure that the object containing those resources does not become eligible for finalization while those resources are still in use. This is generally done by using GC.KeepAlive(). If a derived class adds a Finalize method that cleans up any resource that existed in the parent class but which the parent class doesn't expect a finalizer to clean up, bugs may occur. Encapsulating the resources in their own class can avoid this problem (it's possible that the parent object might get garbage-collected while the resource is in use, but that won't matter if the encapsulating object is properly designed--the encapsulating object's Finalize method won't run until its methods have finished using the resource).

The cost of finalize in .Net

(1) I've read a lot of questions about IDisposable where the answers recommend not using Finalize unless you really need to because of the process time involved.
What I haven't seen is how much this cost is and how often it's paid. Every millisecond? second? hour, day etc.
(2) Also, it seems to me that Finalize is handy when its not always known if an object can be disposed. For instance, the framework font class. A control can't dispose of it because it doesn't know if the font is shared. The font is usually created at design time so the user won't know to dispose it, therefore finalize kicks in to finally get rid of it when there are no references left. Is that a correct impression?
The main problem with finalize is that it blocks an object from being garbage collected. Instead, the finalizer is called, and the object collected "on the next run". Well, technically IIRC the finalizer runs a list of objects in a separate thread. Anyhow, this is not an "every ms" issue, more an "multiple GC runs needed to get rid of the objects.
Finalize is conceptually different than Dispose. Finalize can only free unmanaged resources. Dispose can free managed and unmanaged resources. You should use each as appropriate. (Note that a class with a Finalizer should always implement IDisposable).
Dispose must be called explicitly; Finalize can only be called by the GC.
Update: See my blog post on How to Implement IDisposable and Finalizers: 3 Easy Rules.
I've got a blog post about IDisposable and Finalizing - not about the performance though.
I'll answer your second question.
No, Finalize should not be used in this manner. In fact, with the exception of only a very few fringe cases, you should only override Finalize (or declare a destructor in C#) if the class directly holds unmanaged resources.
The issue you described is one of ownership. The owner of an IDisposable class is responsible for its lifetime and the decision of when to call Dispose. Other parts of code are free to use that class, but since they cannot claim ownership they should not participate in the lifetime management of that class.
Unfortunately I am not very familiar with the Font class nor how it might relate to the specific scenario that was the impetus for your question, but I can make a general statement that might apply to you. If your code did not create the instance (via the constructor) directly then your code should not be considered the owner. In that case you can assume the responsibility for disposal is left to something else.
Finalize is extremely useful as a double check. If a crash or someone's bad code doesn't dispose your object before it goes out of scope, guarantee that its resources will be released in the finalizer.
You can do some fancy footwork in your disposer though by calling GC.SuppressFinalize(this) which will allow you to write a method which will work in both situations and give you a guarantee that the code will work nicely.
You could even fire an MDA if you were writing a framework to remind people that they should dispose your object.
The penalty of the finalizer is basically that you end up pushing your object into the level 2 queue which takes longer to run. If you are consistently using objects and they are finalizing this could result in a level 2 collection running more often than neccessary just to run your finalizer threads.

Categories