views:

269

answers:

9

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.

A: 

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

tathagata
Not sure about your answer there...
Adam
This is not correct. Dispose is used as a form of deterministic finalization, but objects which do not expose IDisposable will still be collected by the GC.
CaptainTom
"-1" you gave refference to GC.Collect() description. there is nothing like "object is only marked for garbage collection, when Dispose() is called"
Arseny
Oops.. okay, I was wrong, Dispose() doesn't have anything to do with garbage collection. Thanks for pointing out.
tathagata
A: 

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

Ardman
But *should* you force a Garbage Collection? In almost all cases: NO!
dtb
-1 You forgot to explain that the code that you just gave him should not be used, and why.
Guffa
But don't use it unless you are really sure that it is going to help. The docs say, for instance: "Use the Collect method when there is a significant reduction in the amount of memory being used at a defined point in your application's code.".I've used it in a program that runs 'jobs' that do a significant amount of work, to clean up between or right after jobs, which did help reduce memory footprint when the program was not doing anything.
Jan de Vos
There are times where you do have to use it though. I've had to use it when a lot of memory intensive operations were running in very quick order. My loops were occurring too fast for the garbage collector and thus I ran out of memory after 4 loops. Forcing garbage collection at the end of each loop made the cleanups happen in a timely manner so the machine didn't run out of memory.
KallDrexx
+5  A: 

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.

Guffa
There is one magic thing about the Dispose method. It will automatically be called on an object created in a `using` statement.
tvanfosson
@tvanfosson: There is still nothing magic about that, and it's the `using` statement that does something specially targeted at the Dispose method, the Dispose method is still just an ordinary method.
Guffa
@guffa - I realize that the method doesn't differ in any material respect from other methods, but I'd say that it's somewhat magical that it gets invoked automatically when exiting a using block.
tvanfosson
+8  A: 

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?

Tim Robinson
OK. Thanks to all of you. I understand very much about Dispose() and garbage collector.
Sharique
A: 

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(); }
dtb
+2  A: 

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).

Adam
As an aside, `Dispose` implementations frequently include a call to `GC.SuppressFinalize(this);` so that finalization won't happen a second time when the object is garbage collected.
Brian
A: 

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.

Incognito
"But generally Dispose makes object as candidate for GC."...um, no.
CaptainTom
Dispose doesn't make an object a candidate - you can keep a reference to the object to stop it from being collected. Dispose should clean up any object-internal resources, if the developer is doing their job correctly.
Adam
Also, on some objects there is a use in setting null - objects with broad scope might be managed in code instead of using scope to determine its reference count. Setting null will make it elligible for GC long before it goes out of scope.
Adam
@Adan and @CaptainTom I didn't mean that it makes for you I mean that purpose is that (to release resources and make candidate for GC). Like you can have method called Add and do multiplication in implementation but purpose is Addition. Hope it makes much clear.
Incognito
@Adam, actually, the compiler will already make it eligible for GC before it goes out of scope at the point that the method no longer makes use of it. See Jon's response here: http://stackoverflow.com/questions/3101530/nesting-reference-type-object-in-inner-scope-has-no-effect-on-garbage-collection/3101582#3101582
Dan Bryant
@Dan oh right, cool. I was more talking about stuff outside of method scope, but still nice to know :)
Adam
A: 

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.

tvanfosson
A: 

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."

Stephen Cleary