Garbage Collection is a technique introduced in Microsoft
.NET that manages memory automatically. This article discusses the concepts of
Garbage Collection and the strategies adopted by Microsoft .NET for handling managed
memory efficiently. It also discusses the methods and properties of the
System.GC class, the class that is responsible for controlling the garbage
collector in the .NET environment.
What is Garbage Collection?
The Common Language Runtime (CLR) requires that you create
objects in the managed heap, but you do not have to bother with cleaning up the
memory once the object goes out of the scope or is no longer needed. This is
unlike the strategies adopted in programming languages like C and C++ where you
needed to cleanup the heap memory explicitly using a free function of C and
delete operator of C++. Garbage collection refers to the strategy adapted by
Microsoft .NET to free unused objects or objects that go out of the scope
automatically.
A "garbage" object is one that is no longer
needed, is unreachable from the root or goes out of the scope in which it is
created. Microsoft .NET uses the information in the metadata to trace the
object graph and detect the objects that need to be garbage collected. Objects
that are not reachable from the root are referred to as garbage objects and are
marked for garbage collection. It is to be noted here that there is a time gap
between the time when an object is identified as garbage and the time when the
object is actually collected. It is also to be noted that objects in the
managed heap are stored in sequential memory locations. This is unlike C and
C++ and makes allocation and de-allocation of objects faster.
Strong and Weak References
The garbage collector can reclaim only objects that have no
references. An object that is reachable cannot be garbage collected by the
garbage collector. Such a reference is known as a strong reference. An object
can also be referred to as a weak reference; another term for a weak reference
is the target. An object is eligible for garbage collection if it does not
contain any strong references, irrespective of the number of weak references it
contains. Weak references are of the following types:
·
Short Weak Reference
·
Long Weak Reference
A short weak reference does not track resurrection while a
long weak reference tracks resurrection. The primary advantage of maintaining
weak references to an object is that it allows the garbage collector to collect
or reclaim memory of the object if it runs out of memory in the managed heap.
The System.GC class
The System.GC class represents the garbage collector and
contains many of methods and properties that are described in this section.
GC.Collect Method
This method is used to force a garbage collection of all the
generations. It can also force a garbage collection of a particular generation
passed to it as a parameter. The signatures of the overloaded Collect methods
are:
public static void Collect();
public static void Collect(Integer int);
GC.GetTotalMemory Method
This method returns the total number of bytes that is
allocated in the managed memory. This method accepts a boolean parameter. If
the parameter is true, it indicates that it should wait for the garbage
collector to finish.
GC.KeepAlive Method
This method extends the life time of an object passed to it
as a parameter. The signature of this method is as follows:
public static void KeepAlive(object objToKeepAlive);
GC.ReRegisterForFinalize Method
This method re-registers an object for finalization, i.e.,
makes an object eligible for finalization. The method signature is as follows:
public static void ReRegisterForFinalize(objectobjToRegister);
GC.SupressFinalize Method
This method suppresses the finalization on an object. The
prototype of this method is:
public static void SupressFinalize(object obj);
GC.GetGeneration Method
This method returns the current generation of an object or
the same of the target of the weak reference. The signature of this overloaded
method is:
System.GC.GetGeneration(object obj);
System.GC.GetGeneration(WeakReferenceweakReference);
GC.MaxGeneration Property
This property returns the maximum number of generations
available.
GC.WaitForPendingFinalizers Method
This method blocks the current thread till the execution of
all the pending finalizers is over. The signature of this method is:
public static void WaitForPendingFinalizers();
The Mark and Compact Strategy
The most commonly used strategy involves the mark and
compact algorithm. This occurs in two phases, Mark and Compact.
Mark
The garbage collector identifies the reachable objects by
starting from the application’s root and builds a graph of the reachable
objects. In order to handle cycles, the garbage collector ignores adding
objects to the graph that have already been added. The objects that are not
reachable from the root are considered garbage.
Compact
In this phase the garbage collector scans the managed heap,
moves the free or available memory to the top and the objects to the bottom of
the heap. The memory holes or free spaces are properly compacted and the
object references updated as necessary. A pointer to the next object in the
managed heap is set up that then indicates that the next object will be created
at that memory location in the heap.
Finalization
When an object of a class is created in the heap that
implements a finalize method, a pointer to the object is stored in the
finalization queue. The garbage collector periodically scans this finalization
queue to get the pointers. When it identifies one, it removes the same from
the finalization queue and adds the pointer to the reachable queue. Then the
finalize method is called on the object and the reachable queue is emptied.
Generations
A generational garbage collector collects the short-lived
objects more frequently than the longer lived ones. Short-lived objects are
stored in the first generation, generation 0. The longer-lived objects are
pushed into the higher generations, 1 or 2. The garbage collector works more frequently
in the lower generations than in the higher ones.
When an object is first created, it is put into generation
0. When the generation 0 is filled up, the garbage collector is invoked. The
objects that survive the garbage collection in the first generation are
promoted onto the next higher generation, generation 1. The objects that
survive garbage collection in generation 1 are promoted onto the next and the
highest generation, generation 2. This algorithm works efficiently for garbage
collection of objects, as it is fast. Note that generation 2 is the highest
generation that is supported by the garbage collector.
Suggested Readings
For further references on this topic please refer to the
following links:
http://msdn.microsoft.com/msdnmag/issues/1100/gci/
http://msdn.microsoft.com/msdnmag/issues/1200/GCI2/
http://www.codeproject.com/dotnet/garbagecollection.asp
Conclusion
Garbage Collection is one of the most striking features
introduced in Microsoft .NET. It is however, not advisable to implement the finalize
method unless it is mandatory. An object that has the finalize method
implemented has to undergo two generations before it gets garbage collected
from the managed heap. Hence, it slows down the operations.