Hi, I want to know what action is performed when we call Dispose() method. Is Object frees all resources quickly on Dispose() call or Dispose() marks the Object is ready for garbage collection. And What happened when we set Object reference to NULL. Actually I have Windows form application in .NET 2.0. And I want to call garbage collector after certain time is passed(For Example after 5 mins) to collect all unreferenced Object.
The object is only marked for garbage collection, when Dispose() is called. <- Update: this is wrong. Dispose() doesn't really do anything, unless it is called either by you or by the compiler (when used in a 'using' construct).
From MSDN -
In most cases, the garbage collector can determine the best time to perform a collection and you should let it run independently. There are rare situations when a forced collection might improve your application’s performance. In these cases, you can induce garbage collection by using the Collect method to force a garbage collection
See this article - http://msdn.microsoft.com/en-us/library/bb384155.aspx
If you actually want to force a Garbage Collection use:
GC.Collect();
Please see this post for reasons why you shouldn't use it:
http://stackoverflow.com/questions/118633/whats-so-wrong-about-using-gc-collect
There is nothing magic about the Dispose method, it's just like any other method. Calling the Dispose method doesn't do any cleanup in the background or change the state of the object, it just does what you have put in the method. What is special about it is that it's defined in the IDisposable interface, so it's the standard way of telling an object to clean up it's resources.
In the Dispose method the object should take care of all unmanaged resources, like database connections and Font objects.
When you free an object you don't have to bother about any managed resources. A structure like a byte array is completely handled by the garbage collector, and you can just leave it in the object when you let it go. You don't need to set any references to null
, when you don't use an object any more, the garbage collector will find the best time to remove it and any objects that it references.
The garbage collector normally works best when you leave it alone, there is no need to tell it when it should collect unused object. It will figure out by itself when that should be done, and usually it does that better than you, as it has access to a lot of information about the state of the memory and the state of the machine that your code doesn't have.
You might feel that you should try to keep the memory usage low, but there is no advantage of that in itself. A computer doesn't work better because it has more free memory left. On the contrary, if your code tries to do cleanup, or forces to garbage collector to do anyhting, it is doing the cleanup when it should be busy doing something more important. The garbage collector will clean up unused object if it's needed.
Dispose
normally frees unmanaged resources owned by the object. Calling Dispose
doesn't trigger garbage collection; your object is collected when there are no longer any references to it, the same as if you'd never called Dispose
.
Setting an object reference to null
just causes that reference to no longer point to that object; you shouldn't normally need to do this (for instance, you almost never need to set local variables to null
).
You almost never need to trigger garbage collection yourself, either. Are you seeing a problem that suggests that you need to run garbage collection every 5 minutes, instead of at the point when the runtime chooses to?
The point of automatic garbage collection is that you don't have to worry about freeing objects. Don't try to "help" the garbage collector.
Objects are garbage collected eventually after they go out of scope. There is no way to "free" an object manually or mark it for faster garbage collection. Just keep in mind which objects are in scope (or referenced from objects in scope).
The Dispose method is just a method. It does nothing related to garbage collection. "Dispose" happens to be the name of the method that is called by the using
statement:
using (var x = expr) { ... }
is basically equivalent to
var x = expr;
try { ... } finally { x.Dispose(); }
An object is elligible for GC when it has no references held against it. If it has references held against it for a certain time period (managed by the garbage collector) it starts to get promoted through what are known as "generations".
The Dispose method is simply a pattern (not a language-imposed object deletion mechanism) to say that the object can now clean up any unmanaged resources, close off any connections etc.
The actions performed by the Dispose method are entirely controlled by the programmer, for all you know, it could be doing nothing.
The garbage collector has no interest in the Dispose methods - but through the Finalizer, its likely that an object's Dispose logic will be called anyway - people following the IDisposable pattern implement the finalizer as a last ditch "you forgot to call Dispose so I'll do it just before the GC kills me" way to clean up resources.
Note that any managed resources will eventually be GC'd (unless references are held) if Dispose is not called. However, unmanaged resources will only be reclaimed when your entire application process finishes (as well as any managed resources with references still held).
For your class objects you are defining what Dispose
will do. You implement IDisposable interface which contains method Dispose
and depends from implementation. But generally the purpose of Dispose
is to release resources (managed/unmanaged) and make object as candidate for GC
.
Concerning setting null
we can say it is useless. It just notes that there is no reference to the object thus it becomes candidate for GC
, but again that there is no need for setting null
as GC
can find that there are no references to the object without that..
For calling Collect
it is not suggested(until you have extreme need and arguments for that) as GC optimized to know what is the right time for Collection
.
Dispose, if implemented correctly, will dispose of any managed resources it has that implement IDisposable and immediately release any unmanaged resources. The object itself will be marked for collection when there are no references to it. Typically the object is used in a using block and the Dispose method is called at the end of the block automatically, with the object falling out of scope and being eligible for collection at that time.
In the general case you are going to cause more problems than you solve by interacting directly with the garbage collector. If you feel that you must do this, it's more likely a signal that you need to refactor your solution -- i.e., you have too much coupling between your classes, resulting in object being kept alive longer than necessary. A cleaner architecture may result in better object lifetime management by the system.
See MSDN for a discussion on how to implement the IDisposable pattern.
Other folks here have sufficiently answered the "how does IDisposable
interact with the garbage collector" and "when should I call GC.Collect
" parts of the question.
I have a blog post that goes into detail about when you should set variables to null
to help the garbage collector (the third part of the question). The short answer is "almost never, unless it's a static variable."