1

In trying to understand the IDisposable i have a few questions that most answers haven't explicitly stated.

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

  2. 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?

GodsCrimeScene
  • 1,260
  • 2
  • 17
  • 35
  • You need to read the stuff that Ravi posted and understand how garbage collection works in C#. Dispose is just a handy place to close files, network connections, SQL server connections, etc. It doesn't free memory. – Corey Mar 01 '13 at 12:41
  • IDisposeable is not magical in any way. It does have any ties to the GC or anything like that. It is simply a pattern, and if it didn't exist in .NET you could have written that interface yourself to the same effect. – Allon Guralnek Mar 01 '13 at 12:42
  • Disposing objects and garbage collection are [**completely** distinct topics](http://stackoverflow.com/questions/339063/what-is-the-difference-between-using-idisposable-vs-a-destructor-in-c) - make sure that you don't confuse the two! – Justin Mar 01 '13 at 12:47

4 Answers4

4

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:

  1. The system has low physical memory.
  2. 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.

  1. Garabge collection when to use
  2. Understanding Object life cycle
Ravi Gadag
  • 15,735
  • 5
  • 57
  • 83
2

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

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
1

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!

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

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

Community
  • 1
  • 1
Justin
  • 84,773
  • 49
  • 224
  • 367
0

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

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276