I'm new to C# and .NET, ,and have been reading around about it.
I need to know why and when do I need to release resources? Doesn't the garbage collector take care of everything? When do I need to implement IDisposable, and how is it different from destructor in C++?
Also, if my program is rather small i.e. a screensaver, do I need to care about releasing resources?
Thanks.
The garbage collector is only aware of memory. That's fine for memory, because one bit of memory is pretty much as good as any other, so long as you've got enough of it. (This is all modulo cache coherency etc.)
Now compare that with file handles. The operating system could have plenty of room to allocate more file handles - but if you've left a handle open to a particular file, no-one else will be able to open that particular file for writing. You should tell the system when you're done with a handle - usually by closing the relevant stream - as soon as you're finished, and do so in a way that closes it even if an exception is thrown. This is usually done with a using statement, which is like a try/finally with a call to Dispose in the finally block.
Destructors in C++ are very different from .NET finalizers, as C++ destructors are deterministic - they're automatically called when the relevant variable falls out of scope, for example. Finalizers are run by the garbage collector at some point after an object is no longer referenced by any "live" objects, but the timing is unpredictable. (In some rare cases, it may never happen.)
You should implement IDisposable yourself if you have any clean-up which should be done deterministically - typically that's the case if one of your instance variables also implements IDisposable. It's pretty rare these days to need to implement a finalizer yourself - you usually only need one if you have a direct hold on operating system handles, usually in the form of IntPtr; SafeHandle makes all of this a lot easier and frees you from having to write the finalizer yourself.
Basically, you need to worry about releasing resources to unmanaged code - anything outside the .NET framework. For example, a database connection or a file on the OS.
The garbage collector deals with managed code - code in the .NET framework.
Even a small application may need to release unmanaged resources, for example it may write to a local text file. When you have finished with the resource you need to ensure the object's Dispose method is called. The using statement simplifies the syntax:
using (TextWriter w = File.CreateText("test.txt"))
{
w.WriteLine("Test Line 1");
}
The TextWriter object implements the IDisposable interface so as soon as the using block is finished the Dispose method is called and the object can be garbage collected. The actual time of collection cannot be guaranteed.
If you create your own classes that need to be Disposed of properly you will need to implement the IDisposable interface and Dispose pattern yourself. On a simple application you probably won't need to do this, if you do this is a good resource.
Resources are of two kinds - managed, and unmanaged. Managed resources will be cleaned up by the garbage collector if you let it - that is, if you release any reference to the object. However, the garbage collection does not know how to release unmanaged resources that a managed object holds - file handles, and other OS resources for example.
IDisposable is best practice when there's a managed resource you want released promptly (like a database connection), and vital when there are unmanaged resources which you need to have released. The typical pattern:
public void Dispose()
protected void Dispose(bool disposing)
Lets you ensure that unmanaged resources are released whether by the Dispose method or by object finalisation.
You don't need to release memory in managed objects like strings or arrays - that is handled by the garbage collector.
You should clean up operating system resources and some unmanaged objects when you have finished using them. If you open a file you should always remember to close that file when you have finished using it. If you open a file exclusively and forget to close, the next time you try to open that file it might still be locked. If something implements IDisposable, you should definitely consider whether you need to close it properly. The documentation will usually tell you what the Dispose method does and when it should be called.
If you do forget, the garbage collector will eventually run the finalizer which should clean up the object correctly and release the unmanaged resources, but this does not happen immediately after the object becomes eligible for garbage collection, and it in fact might not run at all.
Also it is useful to know about the using statement.
The garbage collector releases MEMORY and cleans up - through disposition - elemetns it removes. BUT: IT only does so when it has memory pressure.
THis is seriously idiotic for ressources whree I may want to explicitely release them. Save to file, for example, is supposed to: Open the file, write out the data and - close the file, so it can be copied away by the user if he wants, WITHOUT waiting for the GC to come around and release the memory for the file object, which may not happen for hours.
You only need to worry about precious resources. Most objects you create while programming do not fit into this category. As you say, the garbage collector will take care of these.
What you do need to be mindful of is objects that implement IDisposable, which is an indication that the resources it owns are precious and should not wait for the finalizer thread to be cleaned up. The only time you would need to implement IDisposable is on classes that own a) objects that implement IDisposable (such as a file stream), or b) unmanaged resources.
Related
I have just started with the .NET framework. Today, I was taught about the IDisposable interface and the dispose() method. I was taught a few things regarding it:
dispose() should contain the cleanup code corresponding to an object(like closing any resources occupied by any objects - files or database connections,etc.)
I was also told that in case we don't do it in the dispose() method, the same could be done in the destructor, but that doesn't ensure immediate execution, and we are left to the mercy of GC.
And if at all we don't provide any cleanup code at all, the GC will forcefully terminate all connections to resources that our objects were holding. Hence, we should handle the cleanup code ourselves.
But I was curious as to why doesn't CLR handle this on it's own? It takes care of Memory Management, it takes care of Garbage Collection. So, it should very well know which Object holds onto which resource(s) and when that Object dies off. So, it should be capable of de-allocating those resources as well?
I asked a few people about it. The answer I was given was that it is because we need to close it gracefully, where as GC closes it forcefully. Is it actually the reason?
In .NET there's much more than managed code that the GC knows about. There's like a huge volume of unmanaged code involved: all the file handles, database connections, network sockets, ... all this is plain ol' unmanaged Win32 code. You can't even believe that in almost every single BCL function you are calling from your pretty C# application, you will be hitting like tons of unmanaged functions written in C++ (and may God forbid VB6) and buried deep into the internals of the OS itself. All those functions are allocating unmanaged memory, handles, ... The managed world doesn't know what happens there.
For example every single time you open a file (FileStream) you are basically calling (behind the scenes of course) the CreateFile unmanaged Win32 function. This function allocates an unmanaged file handle directly from the file system. .NET and the GC has strictly no way of tracking this unmanaged code and everything it does. That's why those classes implement the IDisposable interface. So that you could always wrap their instances in using statements and ensure that the Dispose method is always called, even in the event of an exception, and this as soon as possible. The Dispose method will take care of calling another unmanaged function to clean the mess it created.
So basically the way you could think about the IDisposable interface is the following:
The day when we have an operating system written in a fully managed language (something like Midori for example from Microsoft Research) we will probably no longer need IDisposable as the GC will be able to completely replace it as it will have knowledge of everything that happens within this system.
The point of IDisposable and Dispose() is that you should clean up unmanaged memory. That's memory .NET didn't allocate, which came from outside sources and thus the GC cannot know about it. So it cannot clean it up for you automatically. Essentially that's precisely the difference between managed and unmanaged memory ;-)
Generally you should implement Dispose() to clean up whatever unmanaged resources your class uses and implement the finalizer to call Dispose() too. The finalizer is just a safeguard, though. It will make sure that those resources get cleaned up eventually, if the caller forgets to dispose of your class properly.
The IDisposable interface is there to provide you a way to clean up un-managed resources. The CLR only manages your managed resources for you.
In other words, the CLR only knows how to clean up the things that it manages. If you open connections to the rest of the system (like opening files, database connections, etc.), those are your responsibility and you need to tell the CLR how you want it to clean those up for you.
It can only take care of memory management for .NET objects. Any code that needs to use unmanaged resources (because it interacts with a C++ library, for example) falls outside the garbage collector's bailiwick. All that code needs to be told when to release its resources the old-fashioned way.
There's no way for the .Net framework (and the GC) to know how to release a un-managed resource. All it can do, is destroy the reference your managed code has to the resource. It is a lot better to actually call .Close() on a connection to your database server (thereby telling it that the connection should go back into the poll of available connection), than just destroying the reference, and letting it timeout on it's own after a set amount of seconds.
So whenever possible, use the IDisposable interface when referencing un-managed resources!
IDisposable is used when you don't want the GC to handle that particular artifact. The most common example are connections, or file handles. You don't want to wait for the GC to run before releasing a file, or to close a connection to the database, since you don't know when that will happen.
Most people associate IDisposable with unmanaged resources, which is mostly accurate, but fail to remember that finalizers are the proper .NET way to handle those. IDisposable provides a way of deterministicly disposing if that is important to your program.
The IDisposable interface is simply a convention to allow you to deterministically dispose of managed and unmanaged resources. It alone doesn't replace garbage collection or do anything involving the garbage collector itself.
It is more apparent with unmanaged resources because unless these are handled (either in a finalizer or with deterministic disposal) they will remain as a memory leak until the process ends. With managed memory, if you don't deterministically dispose of the items they will be undeterministically collected (assuming eventual eligibility for collection) by the GC, because they are managed (this is also the reason why the dispose pattern doesn't include managed items in the finalizer route).
IDisposable itself doesn't do anything, it is just a recognised interface (and is supported in code with the using keyword) that people expect to find when handling items that use consumable resources, unmanaged memory, external items, etc.
The CLR cannot possibly know when an external item is finished with. That is entirely dependent on the flow of your application. If you happen to also not know when to dispose an object, the finalizer syntax is useful. If you implement a finalizer on a custom class, the garbage collection process will run this finalizer just prior to final collection. This is your last chance to tidy up after yourself.
we use Dispose in order to dispose unmanaged resssource as file access or connection database, because GC don't have information about this unmanaged ressource.
you can also use Finalize, but it's not performant because you save your ressource in finalisation structure, and GC pass in the end of dispose cycle by this finalisation structure, and it's not performant
I was having a discussion with a colleague recently about the value of Dispose and types that implement IDisposable.
I think there is value in implementing IDisposable for types that should clean up as soon as possible, even if there are no unmanaged resources to clean up.
My colleague thinks differently; implementing IDisposable if you don't have any unmanaged resources isn't necessary as your type will eventually be garbage collected.
My argument was that if you had an ADO.NET connection that you wanted to close as soon as possible, then implementing IDisposable and using new MyThingWithAConnection() would make sense. My colleage replied that, under the covers, an ADO.NET connection is an unmanaged resource. My reply to his reply was that everything ultimately is an unmanaged resource.
I am aware of the recommended disposable pattern where you free managed and unmanaged resources if Dispose is called but only free unmanaged resources if called via the finalizer/destructor (and blogged a while ago about how to alert consumers of improper use of your IDisposable types)
So, my question is, if you've got a type that doesn't contain unmanaged resources, is it worth implementing IDisposable?
There are different valid uses for IDisposable. A simple example is holding an open file, which you need to be closed at certain moment, as soon as you don't need it any more. Of course, you could provide a method Close, but having it in Dispose and using pattern like using (var f = new MyFile(path)) { /*process it*/ } would be more exception-safe.
A more popular example would be holding some other IDisposable resources, which usually means that you need to provide your own Dispose in order to dispose them as well.
In general, as soon as you want to have deterministic destruction of anything, you need to implement IDisposable.
The difference between my opinion and yours is that I implement IDisposable as soon as some resource needs deterministic destruction/freeing, not necessary as soon as possible. Relying on garbage collection is not an option in this case (contrary to your colleague's claim), because it happens at unpredictable moment of time, and actually may not happen at all!
The fact that any resource is unmanaged under the cover really doesn't mean anything: the developer should think in terms of "when and how is it right to dispose of this object" rather than "how does it work under the cover". The underlying implementation may change with the time anyway.
In fact, one of the main differences between C# and C++ is the absence of default deterministic destruction. The IDisposable comes to close the gap: you can order the deterministic destruction (although you cannot ensure the clients are calling it; the same way in C++ you cannot be sure that the clients call delete on the object).
Small addition: what is actually the difference between the deterministic freeing the resources and freeing them as soon as possible? Actually, those are different (though not completely orthogonal) notions.
If the resources are to be freed deterministically, this means that the client code should have a possibility to say "Now, I want this resource freed". This may be actually not the earliest possible moment when the resource may be freed: the object holding the resource might have got everything it needs from the resource, so potentially it could free the resource already. On the other hand, the object might choose to keep the (usually unmanaged) resource even after the object's Dispose ran through, cleaning it up only in finalizer (if holding the resource for too long time doesn't make any problem).
So, for freeing the resource as soon as possible, strictly speaking, Dispose is not necessary: the object may free the resource as soon as it realizes itself that the resource is not needed any more. Dispose however serves as a useful hint that the object itself is not needed any more, so perhaps the resources may be freed at that point if appropriate.
One more necessary addition: it's not only unmanaged resources that need deterministic deallocation! This seems to be one of key points of the difference in opinions among the answers to this question. One can have purely imaginative construct, which may need to be freed deterministically.
Examples are: a right to access some shared structure (think RW-lock), a huge memory chunk (imagine that you are managing some of the program's memory manually), a license for using some other program (imagine that you are not allowed to run more than X copies of some program simultaneously), etc. Here the object to be freed is not an unmanaged resource, but a right to do/to use something, which is a purely inner construct to your program logic.
Small addition: here is a small list of neat examples of [ab]using IDisposable: http://www.introtorx.com/Content/v1.0.10621.0/03_LifetimeManagement.html#IDisposable.
I think it's most helpful to think of IDisposable in terms of responsibilities. An object should implement IDisposable if it knows of something that will need to be done between the time it's no longer needed and the end of the universe (and preferably as soon as possible), and if it's the only object with both the information and impetus to do it. An object which opens a file, for example, would have a responsibility to see that the file gets closed. If the object were to simply disappear without closing the file, the file might not get closed in any reasonable timeframe.
It's important to note that even objects which only interact with 100% managed objects can do things that need to be cleaned up (and should use IDisposable). For example, an IEnumerator which attaches to a collection's "modified" event will need to detach itself when it is no longer needed. Otherwise, unless the enumerator uses some complex trickery, the enumerator will never be garbage-collected as long as the collection is in scope. If the collection is enumerated a million times, a million enumerators would get attached to its event handler.
Note that it's sometimes possible to use finalizers for cleanup in cases where, for whatever reason, an object gets abandoned without Dispose having been called first. Sometimes this works well; sometimes it works very badly. For example, even though Microsoft.VisualBasic.Collection uses a finalizer to detach enumerators from "modified" events, attempting to enumerate such an object thousands of times without an intervening Dispose or garbage-collection will cause it to get very slow--many orders of magnitude slower than the performance that would result if one used Dispose correctly.
So, my question is, if you've got a type that doesn't contain
unmanaged resources, is it worth implementing IDisposable?
When someone places an IDisposable interface on an object, this tells me that the creator intends on this either doing something in that method or, in the future they may intend to. I always call dispose in this instance just to be sure. Even if it doesn't do anything right now, it might in the future, and it sucks to get a memory leak because they updated an object, and you didn't call Dispose when you were writing code the first time.
In truth it's a judgement call. You don't want to over implement it, because at that point why bother having a garbage collector at all. Why not just manually dispose every object. If there is a possibility that you'll need to dispose unmanaged resources, then it might not be a bad idea. It all depends, if the only people using your object are the people on your team, you can always follow up with them later and say, "Hey this needs to use an unmanaged resource now. We have to go through the code and make sure we've tidied up." If you are publishing this for other organizations to use that's different. There is no easy way to tell everyone who might have implemented that object, "Hey you need to be sure this is now disposed." Let me tell you there are few things that make people madder than upgrading a third party assembly to find out that they are the ones who changed their code and made your application have run away memory problems.
My colleage replied that, under the covers, an ADO.NET connection is a
managed resource. My reply to his reply was that everything ultimately
is an unmanaged resource.
He's right, it's a managed resource right now. Will they ever change it? Who knows, but it doesn't hurt to call it. I don't try and make guesses as to what the ADO.NET team does, so if they put it in and it does nothing, that's fine. I'll still call it, because one line of code isn't going to affect my productivity.
You also run into another scenario. Let's say you return an ADO.NET connection from a method. You don't know that ADO connection is the base object or a derived type off the bat. You don't know if that IDisposable implementation has suddenly become necessary. I always call it no matter what, because tracking down memory leaks on a production server sucks when it's crashing every 4 hours.
While there are good answers to this already, I just wanted to make something explicit.
There are three cases for implementing IDisposable:
You are using unmanaged resources directly. This typically involves retrieving an IntPrt or some other form of handle from a P/Invoke call that has to be released by a different P/Invoke call
You are using other IDisposable objects and need to be responsible for their disposition
You have some other need of or use for it, including the convenience of the using block.
While I might be a bit biased, you should really read (and show your colleague) the StackOverflow Wiki on IDisposable.
Dispose should be used for any resource with a limited lifetime. A finalizer should be used for any unmanaged resource. Any unmanaged resource should have a limited lifetime, but there are plenty of managed resources (like locks) that also have limited lifetimes.
Note that unmanaged resources may well include standard CLR objects, for instance held in some static fields, all ran in safe mode with no unmanaged imports at all.
There is no simple way to tell if a given class implementing IDiposable actually needs to clean something. My rule of thumb is to always call Dispose on objects I don't know too well, like some 3rd party library.
No, it's not only for unmanaged resources.
It's suggested like a basic cleanup built-in mechanism called by framework, that enables you possibility to cleanup whatever resource you want, but it's best fit is naturally unmanaged resources management.
If you aggregate IDisposables then you should implement the interface in order that those members get cleaned up in a timely way. How else is myConn.Dispose() going to get called in the ADO.Net connection example you cite?
I don't think it's correct to say that everything is an unmanaged resource in this context though. Nor do I agree with your colleague.
You are right. Managed database connections, files, registry keys, sockets etc. all hold on to unmanaged objects. That is why they implement IDisposable. If your type owns disposable objects you should implement IDisposable and dispose them in your Dispose method. Otherwise they may stay alive until garbage collected resulting in locked files and other unexpected behavior.
everything ultimately is an unmanaged resource.
Not true. Everything except memory used by CLR objects which is managed (allocated and freed) only by the framework.
Implementing IDisposable and calling Dispose on an object that does not hold on to any unmanaged resources (directly or indirectly via dependent objects) is pointless. It does not make freeing that object deterministic because you can't directly free object's CLR memory on your own as it is always only GC that does that. Object being a reference type because value types, when used directly at a method level, are allocated/freed by stack operations.
Now, everyone claims to be right in their answers. Let me prove mine. According to documentation:
Object.Finalize Method allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
In other words object's CLR memory is released just after Object.Finalize() is called. [note: it is possible to explicitly skip this call if needed]
Here is a disposable class with no unmanaged resources:
internal class Class1 : IDisposable
{
public Class1()
{
Console.WriteLine("Construct");
}
public void Dispose()
{
Console.WriteLine("Dispose");
}
~Class1()
{
Console.WriteLine("Destruct");
}
}
Note that destructor implicitly calls every Finalize in the inheritance chain down to Object.Finalize()
And here is the Main method of a console app:
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Class1 obj = new Class1();
obj.Dispose();
}
Console.ReadKey();
}
If calling Dispose was a way to free a managed object in a deterministic way, every "Dispose" would be immediately followed by a "Destruct", right? See for yourself what happens. It is most interesting to run this app from a command line window.
Note: There is a way to force GC to collect all objects which are pending finalization in the current app domain but no for a single specific object. Nevertheless you do not need to call Dispose to have an object in the finalization queue. It is strongly discouraged to force collection as it will likely hurt overall application performance.
EDIT
There is one exception - state management. Dispose can handle state change if your object happens to manage an outside state. Even if state is not an unmanaged object it is very convenient to use it like one because of special treatment IDisposable has. Example would be a security context or impersonation context.
using (WindowsImpersonationContext context = SomeUserIdentity.Impersonate()))
{
// do something as SomeUser
}
// back to your user
It is not the best example because WindowsImpersonationContext uses system handle internally but you get the picture.
Bottom line is that when implementing IDisposable you need to have (or plan to have) something meaningful to do in the Dispose method. Otherwise it's just a waste of time. IDisposable does not change how your object is managed by GC.
Your Type should implement IDisposable if it references unmanaged resources or if it holds references to objects that implement IDisposable.
In one of my projects I had a class with managed threads inside it, we'll call them thread A, and thread B, and an IDisposable object, we'll call it C.
A used to dispose of C on exiting.
B used to use C to save exceptions.
My class had to implement IDisposable and a descrtuctor to ensure things are disposed of in the correct order.
Yes the GC could clean up my items, but my experience was there was a race condition unless I managed the clean up of my class.
Short Answer: Absolutely NOT. If your type has members that are managed or unmanaged, you should implement IDisposable.
Now details:
I've answered this question and provided much more detail on the internals of memory management and the GC on questions here on StackOverflow. Here are just a few:
Is it bad practice to depend on the .NET automated garbage collector?
What happens if I don't call Dispose on the pen object?
Dispose, when is it called?
As far as best practices on the implementation of IDisposable, please refer to my blog post:
How do you properly implement the IDisposable pattern?
Implement IDisposable if the object owns any unmanaged objects or any managed disposable objects
If an object uses unmanaged resources, it should implement IDisposable. The object that owns a disposable object should implement IDisposable to ensure that the underlying unmanaged resources are released. If the rule/convention is followed, it is therefore logical to conclude that not disposing managed disposable objects equals not freeing unmanaged resources.
Not necessary resources at all (either managed or unmanaged). Often, IDisposable is just a convenient way to elimnate combersome try {..} finally {..}, just compare:
Cursor savedCursor = Cursor.Current;
try {
Cursor.Current = Cursors.WaitCursor;
SomeLongOperation();
}
finally {
Cursor.Current = savedCursor;
}
with
using (new WaitCursor()) {
SomeLongOperation();
}
where WaitCursor is IDisposable to be suitable for using:
public sealed class WaitCursor: IDisposable {
private Cursor m_Saved;
public Boolean Disposed {
get;
private set;
}
public WaitCursor() {
Cursor m_Saved = Cursor.Current;
Cursor.Current = Cursors.WaitCursor;
}
public void Dispose() {
if (!Disposed) {
Disposed = true;
Cursor.Current = m_Saved;
}
}
}
You can easily combine such classes:
using (new WaitCursor()) {
using (new RegisterServerLongOperation("My Long DB Operation")) {
SomeLongRdbmsOperation();
}
SomeLongOperation();
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Proper use of the IDisposable interface
"IDisposable Interface" article tells:
The primary use of this interface is to release unmanaged resources
Why? Why only unmanaged?
Whole my life I thought its PRIMIRALY use is to release ANY resources: managed (connections to DBs, services proxies, etc) and unmanaged (if they are used in application).
P.S.
I believe there are already questions on this topic, but can't find them.
The underlying connections to db's are not managed, as are file handles and a number of other low-level o/s objects. They are unmanaged. Implementing an IDisposable interface implies that you are not just relying on the garbage collector to release those resources; but you are closing those resources using what ever low-level API that you have available.
Also, I think Eric Lippert's answer (2nd one down) to a similar question is a very good explanation on why you would use IDisposable.
If you read further there is an explanation:
The garbage collector automatically
releases the memory allocated to a
managed object when that object is no
longer used. However, it is not
possible to predict when garbage
collection will occur. Furthermore,
the garbage collector has no knowledge
of unmanaged resources such as window
handles, or open files and streams.
Garbage collector takes care about managed resources. This is why they are managed.
Also, connection resource in your example is not managed resource. .NET connection classes wrap unmanaged resources.
IDisposable.Dispose() is responsible for two things:
Releasing unmanaged resources that the object might own
Dispose()ing other IDisposables owned by the object
Your answer to
Why? Why only unmanaged?
Lifetime of the managed resources are controlled by garbage collector. Which is one of the nice reason that you use C# or Java.
Instead of "unmanaged resources", think "responsibilities". When an object is described as holding "unamanged resources", what that really means is that:
The class has the information and impetus necessary to do something to an outside entity.
If that action never gets done, something else won't work as well as it otherwise would (the effects may be minor or severe).
If the class is doesn't perform the action, nothing else will.
The most common situation where a class will have cleanup responsibilities is when some other entity has been asked to reserve something (be it a file, GDI handle, lock, array slot, memory block, communications channel, or whatever) until further notice. If nothing tells that other entity that the thing it's reserved is no longer needed, it will never allow anything else to use it.
If an object which has an important responsibility to perform some action gets swept away by the garbage collector before fulfilling its responsibility, the action will never get performed. There are two ways this can be prevented:
If an object implements IDisposable, "someone" (either another object or a running procedure) should be slated to call Dispose method before it's abandoned. Dispose shouldn't be thought of as destroying an object, but rather telling an object to carry out its final responsibilities so it may be safely abandoned.
Objects can ask the system to let them know when they've been abandoned, before they're swept away. While such notifications can reduce the danger that a required action might never be performed, it is dangerous to rely upon them since they will often not come in a particularly timely fashion, and in some cases may never come at all.
Objects which provide for the second cleanup approach are called "managed resources".
What happens if I don't call Dispose on the pen object in this code snippet?
private void panel_Paint(object sender, PaintEventArgs e)
{
var pen = Pen(Color.White, 1);
//Do some drawing
}
A couple of corrections should be made here:
Regarding the answer from Phil Devaney:
"...Calling Dispose allows you to do deterministic cleanup and is highly recommended."
Actually, calling Dispose() does not deterministically cause a GC collection in .NET - i.e. it does NOT trigger a GC immediately just because you called Dispose(). It only indirectly signals to the GC that the object can be cleaned up during the next GC (for the Generation that the object lives in). In other words, if the object lives in Gen 1 then it wouldn't be disposed of until a Gen 1 collection takes place. One of the only ways (though not the only) that you can programmatically and deterministically cause the GC to perform a collection is by calling GC.Collect(). However, doing so is not recommended since the GC "tunes" itself during runtime by collecting metrics about your memory allocations during runtime for your app. Calling GC.Collect() dumps those metrics and causes the GC to start its "tuning" all over again.
Regarding the answer:
IDisposable is for disposing unmanaged resources. This is the pattern in .NET.
This is incomplete. As the GC is non-deterministic, the Dispose Pattern, (How to properly implement the Dispose pattern), is available so that you can release the resources you are using - managed or unmanaged. It has nothing to do with what kind of resources you are releasing. The need for implementing a Finalizer does have to do with what kind of resources you are using - i.e. ONLY implement one if you have non-finalizable (i.e. native) resources. Maybe you are confusing the two. BTW, you should avoid implementing a Finalizer by using the SafeHandle class instead which wraps native resources which are marshaled via P/Invoke or COM Interop. If you do end up implementing a Finalizer, you should always implement the Dispose Pattern.
One critical note which I haven't seen anyone mention yet is that if disposable object is created and it has a Finalizer (and you never really know whether they do - and you certainly shouldn't make any assumptions about that), then it will get sent directly to the Finalization Queue and live for at least 1 extra GC collection.
If GC.SuppressFinalize() is not ultimately called, then the finalizer for the object will be called on the next GC. Note that a proper implementation of the Dispose pattern should call GC.SuppressFinalize(). Thus, if you call Dispose() on the object, and it has implemented the pattern properly, you will avoid execution of the Finalizer. If you don't call Dispose() on an object which has a finalizer, the object will have its Finalizer executed by the GC on the next collection. Why is this bad? The Finalizer thread in the CLR up to and including .NET 4.6 is single-threaded. Imagine what happens if you increase the burden on this thread - your app performance goes to you know where.
Calling Dispose on an object provides for the following:
reduce strain on the GC for the process;
reduce the app's memory pressure;
reduce the chance of an OutOfMemoryException (OOM) if the LOH (Large Object Heap) gets fragmented and the object is on the LOH;
Keep the object out of the Finalizable and f-reachable Queues if it has a Finalizer;
Make sure your resources (managed and unmanaged) are cleaned up.
Edit:
I just noticed that the "all knowing and always correct" MSDN documentation on IDisposable (extreme sarcasm here) actually does say
The primary use of this interface is
to release unmanaged resources
As anyone should know, MSDN is far from correct, never mentions or shows 'best practices', sometimes provides examples that don't compile, etc. It is unfortunate that this is documented in those words. However, I know what they were trying to say: in a perfect world the GC will cleanup all managed resources for you (how idealistic); it will not, however cleanup unmanaged resources. This is absolutely true. That being said, life is not perfect and neither is any application. The GC will only cleanup resources that have no rooted-references. This is mostly where the problem lies.
Among about 15-20 different ways that .NET can "leak" (or not free) memory, the one that would most likely bite you if you don't call Dispose() is the failure to unregister/unhook/unwire/detach event handlers/delegates. If you create an object that has delegates wired to it and you don't call Dispose() (and don't detach the delegates yourself) on it, the GC will still see the object as having rooted references - i.e. the delegates. Thus, the GC will never collect it.
#joren's comment/question below (my reply is too long for a comment):
I have a blog post about the Dispose pattern I recommend to use - (How to properly implement the Dispose pattern). There are times when you should null out references and it never hurts to do so. Actually, doing so does do something before GC runs - it removes the rooted reference to that object. The GC later scans its collection of rooted references and collects those that do not have a rooted reference. Think of this example when it is good to do so: you have an instance of type "ClassA" - let's call it 'X'. X contains an object of type "ClassB" - let's call this 'Y'. Y implements IDisposable, thus, X should do the same to dispose of Y. Let's assume that X is in Generation 2 or the LOH and Y is in Generation 0 or 1. When Dispose() is called on X and that implementation nulls out the reference to Y, the rooted reference to Y is immediately removed. If a GC happens for Gen 0 or Gen 1, the memory/resources for Y is cleaned up but the memory/resources for X is not since X lives in Gen 2 or the LOH.
The Pen will be collected by the GC at some indeterminate point in the future, whether or not you call Dispose.
However, any unmanaged resources held by the pen (e.g., a GDI+ handle) will not be cleaned up by the GC. The GC only cleans up managed resources. Calling Pen.Dispose allows you to ensure that these unmanaged resources are cleaned up in a timely manner and that you aren't leaking resources.
Now, if the Pen has a finalizer and that finalizer cleans up the unmanaged resources then those said unmanaged resources will be cleaned up when the Pen is garbage collected. But the point is that:
You should call Dispose explicitly so that you release your unmanaged resources, and
You shouldn't need to worry about the implementation detail of if there is a finalizer and it cleans up the unmanaged resources.
Pen implements IDisposable. IDisposable is for disposing unmanaged resources. This is the pattern in .NET.
For previous comments on the this topic, please see this answer.
The underlying GDI+ pen handle will not be released until some indeterminate time in the future i.e. when the Pen object is garbage collected and the object's finalizer is called. This might not be until the process terminates, or it might be earlier, but the point is its non-deterministic. Calling Dispose allows you to do deterministic cleanup and is highly recommended.
The total amount of .Net memory in use is the .Net part + all 'external' data in use. OS objects, open files, database and network connections all take some resources that are not purely .Net objects.
Graphics uses Pens and other objects wich are actually OS objects that are 'quite' expensive to keep around. (You can swap your Pen for a 1000x1000 bitmap file). These OS objects only get removed from the OS memory once you call a specific cleanup function. The Pen and Bitmap Dispose functions do this for you immediatly when you call them.
If you don't call Dispose the garbage collector will come to clean them up 'somewhere in the future*'.
(It will actually call the destructor/finalize code that probably calls Dispose())
*on a machine with infinite memory (or more then 1GB) somewhere in the future can be very far into the future. On a machine doing nothing it can be easily longer then 30 minutes to clean up that huge bitmap or very small pen.
If you really want to know how bad it is when you don't call Dispose on graphics objects you can use the CLR Profiler, available free for the download here. In the installation folder (defaults to C:\CLRProfiler ) is CLRProfiler.doc which has a nice example of what happens when you don't call Dispose on a Brush object. It is very enlightening. The short version is that graphics objects take up a larger chunk of memory than you might expect and they can hang around for a long time unless you call Dispose on them. Once the objects are no longer in use the system will, eventually, clean them up, but that process takes up more CPU time than if you had just called Dispose when you were finished with the objects.
You may also want to read up on using IDisposable here and here.
It will keep the resources until the garbage collector cleans it up
Depends if it implements finalizer and it calls the Dispose on its finalize method. If so, handle will be released at GC.
if not, handle will stay around until process is terminated.
With graphic stuff it can be very bad.
Open the Windows Task Manager. Click "choose columns" and choose column called "GDI Objects".
If you don't dispose certain graphic objects, this number will keep raising and raising.
In older versions of Windows this can crash the whole application (limit was 10000 as far as I remember), not sure about Vista/7 though but it's still a bad thing.
the garbage collector will collect it anyway BUT it matters WHEN:
if you dont call dispose on an object that you dont use it will live longer in memory and gets promoted to higher generations meaning that collecting it has a higher cost.
in back of my mind first idea came to the surface is that this object will be disposed as soon as the method finishes execution!, i dont know where did i got this info!, is it right?
I was reading this MSDN reference:
Although the garbage collector is able
to track the lifetime of an object
that encapsulates an unmanaged
resource, it does not have specific
knowledge about how to clean up the
resource. For these types of objects,
the .NET Framework provides the
Object.Finalize method, which allows
an object to clean up its unmanaged
resources properly when the garbage
collector reclaims the memory used by
the object. By default, the Finalize
method does nothing. If you want the
garbage collector to perform cleanup
operations on your object before it
reclaims the object's memory, you must
override the Finalize method in your
class.
I understand how GC works but this give me a thought that what is actually CleanUp? Is it just reclaiming memory if it is than why it is having different name?
Beware that this is not the full story either, as finalizing only occurs when the object is garbage collected. In actual fact you should release all unmanaged resources (file handles, mutexes, unmanaged memory) as soon as possible. You should have a look at the IDisposable interface, which defines the Dispose() function.
Wherever possible your disposer should run the same method to free resources as the finalizer would, but then call GC.SuppressFinalize() to stop it from running again (in the finalizer), as there is a minor performance hit when using objects that implement finalizers.
They used a generic phrase such as "clean up" because other things may need to be done besides just reclaiming memory. I can see how this may be a little confusing, since the quote mentions cleaning up resources and reclaiming memory in the same sentence. In that case, what they mean is that the garbage collector reclaims the memory used by the managed code that actually called into an unmanaged library (a wrapper class, for example), but leaves the unmanaged-specific reclamation process up to the developer (closing file handles, freeing buffers, etc).
As an example, I have a Graphviz wrapper library containing a Graph class. This class wraps the functions used to create graphs, add nodes to them, etc. Internally, this class maintains a pointer to an unmanaged graph structure allocated by Graphiz itself. To the .NET Framework, this is merely an IntPtr and it has no idea how to free it during garbage collection. So, when a managed Graph object is no longer being used, the garbage collector frees up the memory used by the pointer, but not the data it points to. To do this, I have to implement a finalizer that calls the unmanaged function agclose (the Graphviz function that releases the resources used by a graph).
An example would be if you wrote a component that used some operating system resource like named pipe or memory mapped file. You could used the finalize operation to release the resource back to the os.
Cleaning up a non-managed resource could include closing network connections, files, database connections, etc.. Of course, it could also include the deallocation of memory for that resource.
CleanUp is here means free up any bounded resource (Harddisk, Network bandwidth, Sound Card, Memory, CPU, etc) and since .NET have no managed reference to unmanaged code, it could just let you do the job at the right moment yourself using Finalize() method before GC swaps it. If you don't CleanUp you would end up some orphan unmanaged code at an unknown state which are still using resources. It's better to implement IDisposable and CleanUp by calling Dispose() on your object.