In this article we will explore the Garbage Collection feature in the .Net framework and the activities required in applications to manage resources complementing the Garbage Collector.
Garbage Collection in Various Environments
One of the new features inherently available in the .Net framework is automatic garbage collection. The term garbage collection can be defined as management of the allocation and release of memory in an application. In C++, developers are responsible for allocating memory for objects created in the application and releasing the memory when the object is no longer needed. COM introduced a new model for memory management - Reference counting. Programmers were only responsible for incrementing the reference count when the object is referenced and decrementing the counter when the object goes out of scope. When the object's reference count reaches zero, the object is deleted and the memory gets freed. Both these schemes are dependent on the developer and result from time to time in memory leaks and application exceptions - conditions that occur at run-time and are not detectable at compilation.
Garbage Collection in .Net
The garbage collector in .Net takes care of bulk of the memory management responsibility, freeing up the developer to focus on core issues. The garbage collector is optimized to perform the memory free-up at the best time based upon the allocations being made. Java developers have enjoyed the benefits of Garbage collection. VB developers are also used to a certain amount of flexibility in these terms and .Net provides full-fledged memory management capabilities for managed resources.
Release Unmanaged Resources - Runtime Garbage Collector
The .Net developer is still responsible for tracking and managing "unmanaged" resources. An example of unmanaged resources is Operating System resources such as file, window or network connection. The framework can track when the unmanaged resource needs to be terminated, but it does not have information on how to terminate the resource and free up the memory. For clean-up of these resources, the framework provides destructors in C# and Managed Extensions for C++ and the Finalize method for other programming languages. The developer must override the Finalize method (or the destructor for C#, Managed Extensions) to release and terminate the unmanaged resources.
When the Garbage collector executes, it does not delete objects which have the Finalize method overridden. Instead, it adds them to a separate list called the Finalization queue. A special runtime thread becomes active and calls Finalize methods for these objects and then removes them from this list. When the garbage collector runs for the next time, these objects are terminated and the memory is released.
Release Unmanaged Resources - Application Developer
The Finalize method should be invoked by the Framework directly and should not allow access to invocation from the application. The type's Dispose or Close method is available to developers for application clean-up . The Finalize method becomes a safety-catch in case the application does not call the Dispose method for some reason. You should implement the Dispose method for the type and invoke the parent type's Dispose method. In the Dispose method, you can call the GC.SuppressFinalize method to prevent the Finalize method from being invoked for this object, as the resources have already been released in the Dispose method. This allows you to implement the Dispose method to release managed as well as unmanaged objects. You can provide a Boolean parameter to the Dispose method to indicate disposal of managed resources. In case the application does not invoke the Dispose Method, the runtime invokes the Finalize method on that object thus avoiding potential problems. The Finalize method can be implemented to invoke the same Dispose method , with a parameter of false , so that only the unmanaged resources are released and the runtime takes care of the managed resources.
The "using" statement available in C# automatically calls Dispose and provides a convenient way to deal with unmanaged resources which are required for a lifetime that extends within the method in which the objects are created. In other languages, you can use the Finally block to release the resources used within a Try block.
Programmatically Invoking the Garbage Collector
In applications with significant memory requirements, you can force garbage collection by invoking the GC.Collect method from the program. This is not recommended and should be used only in extreme cases.
The System.GC class provides methods that control the system garbage collector. Use methods from this class in your application with extreme caution.
NOTE: This article is for purely educational purposes. This article is entirely original, unless specified. Any resemblance to other material is an un-intentional coincidence and should not be misconstrued as malicious, slanderous, or any anything else hereof.