Garbage collection technique is automotive process. Means no one need to call garbage collection program. When it finds that there is need for memory, it runs itself and removes unused object from memory.So, unused objects are automatically released by automatic garbage collection in .NET C# by executing Garbage collector automatically when system has low physical memory.

Whats does Garbage means in C#?

"Garbage" consists of objects created during a program’s execution on the managed heap that are no longer accessible by the program. Their memory can be reclaimed and reused with no averse effects.

Advantage of Garbage Collector

  1. No worry about memory management
  2. Allocate object memory on managed heap efficiently.
  3. Reclaims objects that no longer being used, clears their memory and keeps the memory for future allocations.
  4. Provides memory safety by making sure that object cannot use the content of other object.

Let take a look at working Console application example of how we can call garbar collector explicitly in .NET C# but we before we proceed for that, generally we know that, we write destructor to destroy the object which is created by constructor, but in .NET destructor not runs automatically. Let us see how it works.

using System;

namespace GarbageCollection
{
    public class GarbageCheck
    {
        public GarbageCheck()
        {
            Console.WriteLine("Reserve memory");
        }
        ~GarbageCheck()
        {
            Console.WriteLine("Free memory");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            GarbageCheck g = new GarbageCheck();
            g = null;

            Console.ReadLine();
        }
    }

}

Output:

garbage-collection-in-c-sharp-min.png

Now, if we want to free all unused object from memory, we call garbage collector explicitly using GC.collect() method. Here is GC is garbage collector class. In below example we are removing all unused object from memory using GC.collect() .

using System;

namespace GarbageCollection
{
    public class GarbageCheck
    {
        public GarbageCheck()
        {
            Console.WriteLine("Reserve memory");
        }
        ~GarbageCheck()
        {
            Console.WriteLine("Free memory");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            GarbageCheck g = new GarbageCheck();
            g = null;
            GC.Collect();

            Console.ReadLine();
        }
    }

}

garbage-collection-in-c-sharp-two-min.png

Note: Calling GC.Collect is discouraged by Microsoft and is generally to be avoided. The garbage collector is a very intelligent mechanism, and has much more information at its disposal than you do when it evaluates whether or not a collection is needed.

How Garbage Collector works

Garbage collector initialized by CLR and allocate memory for object, this memory is known as managed heap. Managed heap organized into form of Generation that contains reference of objects. Garbage Collector divides complete managed heap into three generation as:

Generation 0

Generation 1

Generation 2

Generation is a portion of memory from managed heap that handle long-lived and short-lived objects. Generation 2 memory size is always greater than generation 1 memory and generation 1 memory is always greater than generation 0 memory.

When application starts execution then always newly created object comes inside generation 0.

Let's understand how internal process going on...

Process first

Whenever new object is created, it comes into generation 0.

When Generation 0 is completely filled and application is trying to create a new object then:

  1. Garbage collector perform an operation known as collection means.
  2. Garbage collector examines all the object that present in generation 0, identifies idled objects and objects in use.
  3. Idled objects are destroyed or placed in finalization queue.
  4. Objects in use that survive in generation 0 and promoted to next generation i.e. generation 1 so that generation 0 will become empty.
  5. Now again newly created object place inside generation 0.
  6. After some performing collection generation 0 and generation 1 will be completely filled.

Process second

When generation 0 and generation 1 completely filled and application is trying to create a new object then:

  1. Garbage collection again perform the operation collection means.
  2. Examines all the object present in generation 0 and generation 1, identifies idled objects and objects in use.
  3. Idled objects are destroyed or placed in finalization queue.
  4. Objects in use that survive in generation 1 and promoted to the next generation i.e generation 2, so that generation 0 and generation 1 will become empty.
  5. Now again newly created object will be placed in generation 0.
  6. After some performing so many collections generation 0, generation 1 and generation 2 will be completely filled.

Process third

When generation 0, 1, 2 are completely filled and application is trying to created a new object then:

  1. Garbage collector again perform the operation collection means.
  2. Examine all the objects in generation 0, generation 1 and generation 2.
  3. Divided object into idled objects and objects in use.
  4. Idled objects are destroyed or place in Finalization queue.
  5. Objects in use that survive in generation 2 remain in generation 2.
  6. Now newly created object placed inside generation 0.
  7. Generation 2 is also known as full garbage collection, because it reclaims all objects from all generations.

Performing the collection of generation 0 garbage collector will take 1/10th of a nano second time which is less than a page cycle.

How garbage collector identify that objects in use or not

Garbage collector use following information to determine whether objects are in use or not:

  1. Stack roots - Stack variables provided by JIT compiler and stack walker.
  2. Garbage collection handler - Handles that points to managed object and can be allocated by user code or by CLR.
  3. Stack data - Static object in application domain that could be referencing other objects. Each application domain keep track of its static objects.

In Microsoft’s implementation of the .NET framework the garbage collector determines if an object is garbage by examining the reference type variables pointing to it. In the context of the garbage collector, reference type variables are known as “roots”. Examples of roots include:

  • A reference on the stack
  • A reference in a static variable
  • A reference in another object on the managed heap that is not eligible for garbage collection
  • A reference in the form of a local variable in a method

Consider the following example (source)

void CreateList()
{
	var myList = new List<object>();
	myList.Add(new object());
	myList.Add(new object());
	myList.Add(new object());
	Console.WriteLine("Objects added!");
}

When the method starts to execute, a List<object> is instantiated on the managed heap along with several objects. The List contains a root to each of the objects, and the stack contains a root to the List. While the method is executing, all of these roots are accessible from within the program and are considered to be “active”. When the method finishes executing, the stack is cleaned up, removing the root pointing to the List. The List is now no longer accessible within the program. All of the roots contained by the List (those pointing to the objects) are now considered to be "inactive".

The garbage collector identifies garbage by examining an application’s roots. Objects which have no active roots pointing to them are considered to be garbage.