Working of Garbage Collector: Part I

In this article I will give you an introduction of how C# garbage collector works.

In shortly I can introduce garbage collector as a worker which runs on separate thread and keeps the developer away by the memory management of the program.

Basically it gives two advantages to the programmers

  1. Programmers can mainly focus on the logic of the program - in early languages such as unmanaged C++ programmers have to spend lot of their development effort on this memory management, even for well experienced programmers.
  2. Second one is it helps to keep integrity of the program, if you have ever used unmanaged C++ you may experienced, How many times trying to de allocate memory of object which is already de-allocated. I'm sure at least once

So garbage collector keeps you away by this burden of memory management. By the way it can do the job perfectly.

So if the garbage collector doing it's job perfectly, how is it?

To answer this question you must first understand the way memory is used by the C# program. Basically there are two parts in the memory, called stack and heap.

You must know few things about Stack

Stack is:-

  1. is considerably small and keeps the references to the heap objects.
  2. Each new Thread creates new stack frame.
  3. Value types (structs in C#-usually 16bytes or less) are used to live in the stack.
  4. Faster in accessing stack elements.

Heap is:-

  1. Large memory area and all the objects (reference types) used to live in the heap.
  2. You can not directly access the elements in heap without any reference from the stack.

Garbage Collector Algorithm

Each thread use to create new stack in the memory, as I told above this stack contains the pointers to the objects in the heap. This pointer refers to an object in the heap or it is null. (If we tried to access null pointer it throws NullReferenceException in .Net Framework)

So now we will move on to garbage collection algorithm. When garbage collection starts it assumes that all objects in the heap are as garbage.

Then garbage collector achieves its goal by three phases:

Phase 1: Examine phase

In this phase garbage collector identify roots by examine the thread stack. What are these roots in our c# class?

Usually

  1. Static fields
  2. Method Parameters
  3. Local Variables
  4. CPU registers

These four types can be identified as roots in our class.

Keep in mind that value types are never become roots, because as I told above they used to live in the stack and destroys when stack blows.

Phase 2:  Marking phase

During this phase what garbage collector doing is when it is moving through the thread stack while identifying the roots, if it finds out that root refers to an object in the heap (this means the object is accessible to the outside world)marks it.

Marking is done by turning on the sync block of the each object.


Another thing must be remember here is one object can refers to another object by inside itself. In this scenario marking the first object caused to mark the second one as well.

Let's consider this scenario,

class Obj1 { }

 

    class Obj2

    {

        static Obj1 a;

 

        static void Main(){

            a = new Obj1();

        }

    }

In this simple example we can see class Obj2 internally refers to the Obj1.What is inside memory does can be shown in a diagram this way


So simply what happens when garbage collection occurs is marking Obj1 causes to mark Obj2 as well,as I told above.

Finally all unreachable objects(unmarked objects) are considered as garbage,and the memory occupied by them can be reclaimed back. In the above example Obj3 and Obj5 memory can be reclaimed to the user.

Phase 3: Compact Phase

This is final phase of one collection cycle.After reclaiming the unmarked objects memory now there is only the non-garbage objects in the memory.so in this phase garbage collector shfits those objects down the memory,and moves the next-object-pointer to the next free memory loacation(when you create another object using new keyword in c# that object places here and moves the next-object-pointer ahead,when ever if there is no enough space available new throws OutOfMemoryException).


Although I have discussed .Net framework garabage collection algorithm in shortly,there are some more things to discuss such as what happens when we include finalizers in our classes definition? When to use or not finalizers?

One thing you must remember is.Net garbage collector is well written and well tuned at the same time it is self-tuninng tool(Later I will discuss about generations and self-tunnig of garbage collector).So it is always better to let the garbage collector to do it's duty himself.