Garbage collection, and dispose questions. Appreciate some brainy assistance

236 views Asked by At

Does the Dispose method use Garbage collector to clear resources?
Also is there any benefit in using Dispose instead of finalizers?
I have searched for answeres but nothing very good at explaining it so far.
Thank you.

4

There are 4 answers

6
Habib On BEST ANSWER

Does the dispose () method use Garbage collection to clear resources?

No. Dispose() is used for releasing unmanaged resources (usually). It doesn't have anything to do with GC.

See: IDisposable interface

The primary use of this interface is to release unmanaged resources. 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 calls the finalizer (destructor) of an object and if that object implements IDisposable then the finalizer can have a call to Dispose(false)

0
supercat On

Some objects, in order to behave as specified, need outside entities to do things on their behalf. In some cases, outside entities will be able to do everything that's necessary before a method returns. In other cases, however, a method will need to return after having asked an outside entity keep doing something until further notice (but without having given it such notice). The object thus acquires a responsibility to let the outside entity know when its services are no longer required.

The purpose of IDisposable is to provide a standardized way by which an object can be told "Your services will no longer be required, so if you've asked any outside entities to start doing something on your behalf so you could in turn use it to satisfy your customers, you should tell them to stop doing so." It generally does not free up any memory (except in cases where an outside entity has reserved some memory to help it satisfy the object's needs), and in many cases need not actually do anything (if no outside entities are doing anything on behalf of some object, nobody will need to be told to stop acting on its behalf).

Finalizers exist primarily to deal with the possibility that objects which implement IDisposable might get abandoned without their dispose method having been called. It effectively tells an object "It looks as though you've been abandoned, so you should probably clean up". Although Finalize can serve as a "safety net", it should not be considered reliable; generally, if an object which has a finalizer is wrongfully abandoned, the finalizer will get run "sometime", but there's generally no guarantee of timeliness. Thus, when an object which has asked an entity to do something on its behalf is no longer needed, it should be told immediately (via Dispose) rather than abandoned. In a properly-written program, few finalizers should ever run.

0
Ricibob On

Lots of answers here focusing on freeing UNmanaged resources - which is indeed a role of Dispose. Howerver important to note that this case (of having to deal with raw manged resources, i.e os file handles, socket handles etc) is very rare. In almost all cases we deal with these resources via MANAGED objects - that themselves implement IDisposable to free their resources.
So in reality the common reason for writing dispose is not about WHAT resources are freed but rather WHEN resources are freed. I.e in general we write Dispose because our objects contains (managed) members that control resources (eg TCPClient that holds open a socket). By implimenting IDispose we allow users of the our class to control WHEN that MANAGED resource is freed - either by applying a using statement or by explicitely calling Dispose.

4
SLaks On

Dispose() is a regular method.
It has nothing to do with the garbage collector.

Calling methods like Dispose() allow you to release unmanaged resources that the garbage collector doesn't know about, like native file handles.
You should also do that in a finalizer, so that they won't leak if your callers forget to call Dispose(). However, calling Dispose() allows them to be released immediately, as opposed to waiting for the garbage collector to dispose your object.

If your object holds other objects that in turn have unmanaged resources, you should implement Dispose() but not a finalizer. Dispose() allows your callers to immediately dispose the deeper unmanaged resources, but you don't have anything for a finalizer to do. (the unmanaged resources should be released by the inner finalizers)

To implement this cleanly, use the Dispose(disposing) pattern, which cleanly delineates where to dispose managed and unmanaged resources.