Working of Garbage Collector - Part II

In part one of this I have explained you main lifecycle of c# garbage collector. This cycle includes

  1. Examine phase 
  2. Marking phase
  3. Compacting phase

By this article I'll explain you how garbage collector is well tuned for its maximum performance in order to reclaim the memory back to the user. And also it is a self tuning tool as well. Later I'll discuss about how what happens when we include ''finalizers'' in our types.

Basically if we consider computers nowadays, they are usually with large amounts of memory, so if our programs use all over this memory then the garbage collector must reclaim all that memory to the user-definitely it will take more time to collect more area of memory.

For as a day to day example think about our garden if you are cleaning it every morning suppose it will take 1 hour, so what is the situation if the garden is twice as big as now then you may need 2 hours for cleaning (only other choice is use servant with you-this is not possible with current garbage collector of c# since it is a single tool)

How garbage collector overcomes the situation

The answer is it uses programs memory in Generations because of always collecting part is more faster than collecting all the area of memory. So garbage collector divides memory in to 3 parts

  1. Generation 0 - usually 128 or 256 KB in size
  2. Generation 1 - usually 2MB in size
  3. Generation 2 - usually 10 MB or large in size

Usually the object you created newly are placed on generation 0 and at the beginning there is only a single generation (generation 0).


Figure 1.

Suppose now garbage collection occurs (generation 0 is full) and it goes through the above three steps which I explained you part I of this article. Here is the memory after three steps of the above life cycle. What it specially does during the compacting phase is move all the marked (non-garbage) in to place which is identified as generation 1.

Memory at the end of marking phase


Figure 2.

Note that there is only single generation (generation 0) yet

Memory at the end of compacting phase


Figure 3.

Note that older objects (Obj1, Obj3) are moved to new generation (generation 1)

After this garbage collector does not collect generation 1 always and always, it usually collecting generation 0 which is typically small in size and becomes faster to collect as well. If and only if memory collected by generation 0 is not sufficient for the program to run then only garbage collector moves in to generation 1 and collects it as well. After collecting the generation 1, then all the marked objects by generation 0 and generation 1 are now moved into generation 2.

Simply the above processes are happening over and over, but remember there are only three generations (there is no such generation called generation 4 or generation 5 like that....)

So according to the above scenario you can see that garbage collector is always collecting smallest area of memory (generation 0) which makes it well performed for its duty, only when garbage collector needs more memory it goes up to higher generation and collect them.

Finally at the same time garbage collector is self tuned as well, which means if garbage collector can collect more garbage by cycle(more memory is reclaimed at one cycle) then it can adjust the generation 0 into 128 of size otherwise into 256 of size like that. This further improves the performance.

So as I can understand garbage collector can do its job well than us, so it's better to let garbage collector to do its job always, whenever possible.