It has been long time I have visited to Garbage Collection. I learnt on 10-12 years. I have been visiting again and this article I want to write about my learning. In nutshell, Garbage collector manages the allocation and releasing the memory of the application. It means for developer for managed code, they don’t have to write code to perform memory management tasks. It eliminate common problems, such forgetting to free an object and cousing memory leak.
When a new process starts, .NET runtime reserves a contiguous region of address space for the process, that is called managed heap. The managed heap maintains a pointer to the address where the next object in the heap will be allocated. When application create first reference type, memory allocated for the type at the base address of the managed heap. When application next object, it create following the first object and so on as long as memory space is available. Allocating memory from the managed heap is faster than unmanaged memory allocation. Because the runtime allocates memory for an object by adding a value to a pointer, it’s almost as fast as allocating memory from the stack.
Runtime determines what is the best time to run garbage collection. Once it start these the steps it performs:
Garbage Collector runs in following scenarios:
To improve the performance of garbage collection, Runtime categorized objects in managed heap in different generations. It happens due to following considerations:
As mentioned above managed heap is divided into 3 generations 0,1 and 2. Newly created object always created in generation 0. If those objects are survived during Garbage collection, they are promoted to generation 1. If they survived during generation 1 garbage collection then they promoted to generation 2. And garbage collection in generation 2 rarely happens.
Garbage collection on generation 0 happens more frequently. When application create new object, it gets created. in generation 0 unless it large object like array. Large objects are created in large object managed heap. If application When application attempt to create new object when generation 0 is full, Garbage collection triggers. It examines generation 0 first and most of the large memory is released in this generation only.
If any object survived in generation 0 garbage collection, they are promoted to generation 1, assuming they are going to live for long time. Garbage collection on generation 1 happens only if generation 0 garbage collection could free up enough memory.
If any object survived during genration 1 garbage collection, then they are promoted to generation 2. Of course generation 2 garbage collection only happens if above two gc are not able to free up the space. Static variable are stored in this category.
Garbage Collection on generation 2 happens when system is running out of memory or user call GC.Collect() method in the code.
When the garbage collector detects that the survival rate is high in a generation, it increases the threshold of allocations for that generation. The next collection gets a substantial size of reclaimed memory. The CLR continually balances two priorities: not letting an application’s working set get too large by delaying garbage collection and not letting the garbage collection run too frequently.
Most of the time we work with managed object, but sometime we need to use object which is are not managed like file handle, Database connection, Windows handle. although Garbage collector able to determine lifetime of the object but it doesn’t know how to release memory for those object. In that case our code should be responsible for clearing those objects. Generally it is done by implementing IDisposable interface and explicitly by calling Dispose() mahod. It can also be done by implementing Object.Finalize() method which is destructor of the class. But it’ll not guarantee when your resource will be released or destroyed.