C sharp - Garbage Collection

Garbage Collection (GC) – Automatic Memory Management in C#

1. What is Garbage Collection?

  • In C#, memory for objects is allocated on the heap.

  • When objects are no longer used, the Garbage Collector (GC) automatically frees that memory.

  • This prevents memory leaks and reduces programmer workload compared to manual memory management (like in C/C++ with free or delete).


2. How It Works

  1. The program creates objects on the heap.

  2. When objects are no longer referenced, they become eligible for garbage collection.

  3. The GC runs periodically and reclaims unused memory.

You don’t need to call it manually most of the time — it’s automatic.


3. Generations in Garbage Collection

C# uses a generational GC model to improve performance:

  • Generation 0 – Short-lived objects (e.g., temporary variables, local objects).

  • Generation 1 – Objects that survived one collection.

  • Generation 2 – Long-lived objects (e.g., static data, global objects).

Why? Most objects are temporary, so Gen 0 is collected frequently. Gen 2 is collected less often to save time.


4. Forcing Garbage Collection

Normally, you let GC do its job. But if necessary, you can force it:

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Forcing garbage collection...");
        GC.Collect();   // Forces garbage collection
        GC.WaitForPendingFinalizers(); // Waits for cleanup
    }
}

⚠️ Forcing GC is usually not recommended (it hurts performance). Let .NET manage it.


5. Finalizers (Destructors)

  • A finalizer (~ClassName) is called by the GC before an object is reclaimed.

  • Used to clean up unmanaged resources (like file handles, database connections).

class Demo
{
    ~Demo()
    {
        Console.WriteLine("Finalizer called before object is destroyed.");
    }
}

But: finalizers are unpredictable (you don’t know when they’ll run).


6. IDisposable and using

For deterministic cleanup (especially unmanaged resources), use IDisposable and the using statement.

class FileHandler : IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("Cleaning up resources...");
    }
}

class Program
{
    static void Main()
    {
        using (FileHandler f = new FileHandler())
        {
            Console.WriteLine("Working with file...");
        } // Dispose() is automatically called here
    }
}

7. Best Practices

  • Don’t force GC (GC.Collect) unless absolutely necessary.

  • Prefer using and IDisposable for resource cleanup.

  • Avoid finalizers unless you really need unmanaged resource handling.

  • Rely on .NET’s GC — it’s highly optimized.