Question

GC is for managed objects and Finalize is for unmanaged objects thats what I have been reading. Dispose is implicit and Finalize is Explicit is what I have been reading. Can somebody give me one example of one module in which all three thing have been used for different reasons?

Was it helpful?

Solution

GC is garbage collection. It is the automatic memory management, that handles cleanup of objects allocated on the managed heap. The .NET GC employs a mark and sweep algorithm. When a garbage collection occurs it basically considers all object in the part of the heap to be cleaned as recoverable. Then it goes through a marking process where it scans for roots. I.e. it identifies objects that are still in use by the application. Having done that the remaining objects are eligible for cleanup. The heap may be compacted as part of the cleanup.

Dispose and finalizer methods both offer an option for cleaning resources, that are not handled by GC. E.g. this could be native handles and the like. They have nothing to do with reclaiming memory on the managed heap.

Dispose must be called explicitly on a type which implement IDisposable. It can be called either through the Dispose() method itself or via the using construct. The GC will not call Dispose automatically.

A finalizer or destructor (as the language specification calls it) on the other hand will automatically be called sometime after the object was eligible for cleanup. Finalize methods are executed sequentially on a dedicated thread.

Dispose() allows deterministic cleanup of resources while a finalizer can act as a safety net in case the user doesn't call Dispose().

If a type implements a finalizer, cleanup of instances is delayed as the finalizer must be called prior to cleanup. I.e. it will require an additional collect to reclaim the memory for instances of the type. If the type implements IDisposable as well, the Dispose method can be called and then the instance can remove itself from finalization. This will allow the object to be cleaned up as if it didn't have a finalizer.

If you want to dig into this, I recommend CLR via C# by Jeffrey Richter. It is a great book and it covers all the gory details of this (I left out a number of details). The new 3rd edition was just released.

OTHER TIPS

One of the benefits of .NET is the garbage collector. In many languages, every piece of memory must be managed by the developer- any allocated memory should eventually be released. In .NET (C#), the Garbage Collector (GC) will take care of the process of releasing memory for you. It tracks the usage of your objects, and after they become "unrooted" (ie: there are no references within your application to that object, directly or indirectly), the object's memory is automatically cleaned up.

Dispose, or more particularly, IDisposable and the Dispose pattern, is used to handle resources separately from the GC. Some resources need to be cleaned up explicitly, for various reasons. This includes using a "native" API (where .NET doesn't know about the allocated memory), using a resource that wraps native handles, etc. In order to handle this cleanly, you implement IDisposable and the Dispose pattern.

Finalization occurs on objects when they are about to be collected by the garbage collector. This provides a "safety-net" where by an object that should have been disposed can still be cleaned up, if a bit later than ideal. By implementing a finalizer, you can guarantee unmanaged resources are always released.

The problem with most samples is that there are multiple reasons to use IDisposable, and the proper implementation differs depending on the reason you are using it. For example, if you wrap a native resource directly, you should implement a finalizer, but if you encapsulate another IDisposable type, a finalizer is not necessary, even though you should still implement IDisposable. In order to address this, I've written about IDisposable and finalization in depth on my blog, describing the multiple reasons you would use IDisposable, and different patterns for different reasons.

You may just want to read what I consider the definitive article on IDisposable, finalizers and garbage collection, Shawn Farkas' CLR Inside Out: Digging into IDisposable.

This article leaves very little doubt about the subject.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow