# Fundamentals of Garbage Collection

## 1.Introdiction to .NET Memory Management

When a .NET application runs, memory is primarily divided into two areas:

*   **Stack**
    
*   **Heap**
    

Local variables and method calls are handled by the **Stack**.  
Objects created using the `new` keyword are allocated on the **Heap**

But this raises an important question:

> If objects are continuously allocated on the heap, who deletes them?

In languages like C and C++, developers must manually release memory using mechanisms such as `free()` or `delete`. Failure to do so can result in memory leaks, dangling pointers, or memory corruption.

In contrast, .NET uses an automatic memory management system called the **Garbage Collector (GC)**.

The Garbage Collector automatically identifies objects that are no longer in use and reclaims their memory, allowing developers to focus on application logic rather than manual memory cleanup.

## What is Stack.?

The **Stack** is a region of memory used to manage method execution.

It is responsible for storing:

*   Method parameters
    
*   Local variables
    
*   Return addresses
    
*   Execution context
    

When a method is called, a **stack frame** is created.  
Each stack frame contains everything required for that specific method call.

When another method is called inside it, a new stack frame is placed **on top** of the previous one.

This is why it is called a *Stack* —  
because data is added and removed in a **Last-In, First-Out (LIFO)** order.

## What Happens When a Method Returns?

When a method finishes execution:

*   Its stack frame is removed.
    
*   All its local variables go out of scope.
    
*   The memory used by that frame is automatically reclaimed.
    

If the method that called it also returns, its stack frame is removed as well. Eventually, if all methods complete, the stack becomes empty again. Stack memory management is extremely fast because it simply moves a pointer up and down.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1771082828058/5002163b-0a57-4cef-b54d-22ce2b52da4a.jpeg align="right")

when code call another method

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1771082991435/c4e1beb0-ba66-4289-a55f-136d011d1179.jpeg align="center")

same thing happened again it added, Method parameters, return address, and local variables on top of previous stack frame.

why it called stack.? because information will get stacked on top of another

what happened when will u return result from method.? so in this at moment when you return, all the local variables go out of scope and are destroyed. and if return from first method also we will back at where we started, empty stack

## What is Heap.?

this is also a block of memory, every new object in .NET is creating into heap like

```csharp
MyClass Obj = new MyClass();
```

lets see an program

```csharp
using System;

class Person
{
    public string Name;
    public int Age;

    public void Greet()
    {
        Console.WriteLine($"Hi, I am {Name} and I am {Age} years old.");
    }
}

class Program
{
    static void Main()
    {
        Person p1 = new Person();
        p1.Name = "Hasan";
        p1.Age = 25;

        p1.Greet();
    }
}
```

First, `p1` is created in the Stack as a reference variable. At this moment, it does not hold an object; it only has space to store a memory address and initially contains `null`.

Then the `new Person()` statement executes. This allocates memory in the Heap and creates a new `Person` object there. The fields of the object are automatically initialized with their default values (`Name = null`, `Age = 0`).

After the object is created in the Heap, its memory address is assigned to the reference variable `p1` in the Stack. Now `p1` points to that Heap object.

When we assign values using `p1`, such as setting properties or fields, those values are stored inside the Heap object. The Stack continues to store only the reference (memory address), while the actual object data resides in the Heap.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1771179613465/eb25016c-a1ec-4af9-8fec-9836d2744177.jpeg align="center")

now on stack method will reference from heap memory.

if method if return i will removed from stack but in heap will still exist like

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1771179763411/ee4af28b-c5b8-4cb8-8dc9-e7b5678b39ba.jpeg align="center")

This is interesting, right? When a method finishes executing, its local variables and parameters go out of scope, but the object in the heap may still exist. In this case, the object becomes dereferenced because the variables and parameters that were referencing it have gone out of scope. A dereferenced object continues to exist in the heap, but it is not released immediately. Instead, it becomes eligible for garbage collection, and the .NET runtime will clean it up later.

The .NET Framework postpones cleaning up dereferenced objects because heap cleanup takes time. By delaying this process, the application can run more efficiently and perform better. This cleanup process is called garbage collection, and it runs periodically in the background.

When the runtime starts garbage collection, it scans the heap and identifies objects that are no longer referenced by any active variables, parameters, or reachable objects in the program. It then deallocates those unreachable objects and frees the memory.

## How Data Stores in Stack & Heap

In our code have Used parameters like Integer & String  
The `int` type belongs to a special category called **value types**. Value types store their actual data directly in the memory location where they are declared.

If a value type variable (like `int`) is declared inside a method, its value is stored directly in the **Stack** as part of the method’s stack frame. When the method ends, the stack frame is removed, and the value is automatically destroyed.

If a value type is part of an object (for example, `int Age` inside a class), it is stored in the **Heap** because it becomes part of the object’s memory block.

Reference types (such as `class`, `string`, and `array`) work differently. The reference variable is stored in the **Stack**, but the actual object is created and stored in the **Heap**. The Stack holds only the memory address, while the object’s data remains in the Heap.

## Value Type:-

A value type is a type of variable in which both the type and the actual value are stored together in memory. The variable directly contains its data rather than a reference to another memory location.

For example, if I declare a local integer variable with a value of 1234, both the `int` type and the value `1234` are stored together in the Stack as part of the method’s stack frame. The variable itself holds the actual data, not a memory address pointing somewhere else.

This is why value types are typically faster to access and automatically removed when the method’s stack frame is destroyed.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1771180629186/99299887-2744-44d1-b876-3c9e32d41962.jpeg align="center")

All Value type

<details data-node-type="hn-details-summary">
<summary>See All Value Type</summary>
<table style="min-width: 50px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>sbyte</p></th><th colspan="1" rowspan="1"><p>long</p></th></tr><tr><td colspan="1" rowspan="1"><p>byte</p></td><td colspan="1" rowspan="1"><p>float</p></td></tr><tr><td colspan="1" rowspan="1"><p>char</p></td><td colspan="1" rowspan="1"><p>double</p></td></tr><tr><td colspan="1" rowspan="1"><p>short</p></td><td colspan="1" rowspan="1"><p>decimal</p></td></tr><tr><td colspan="1" rowspan="1"><p>unsort</p></td><td colspan="1" rowspan="1"><p>bool</p></td></tr><tr><td colspan="1" rowspan="1"><p>int</p></td><td colspan="1" rowspan="1"><p>enum</p></td></tr><tr><td colspan="1" rowspan="1"><p>unit</p></td><td colspan="1" rowspan="1"><p>struct</p></td></tr></tbody></table>
</details>

## Reference Type:-

![](https://cdn.hashnode.com/uploads/covers/6884d13c04655ac461ea86d5/eacef68b-df3f-40ad-b106-1eb0ef54029f.jpg align="center")

a reference type is a type of variable that refers to a value stored on the heap. in this variable can be on stack but i will refer a value on heap  
reference type can exist on the stack and on the heap just like value types, but they will always refer to a value on heap.

![](https://cdn.hashnode.com/uploads/covers/6884d13c04655ac461ea86d5/b6d12568-bfc7-481c-ad90-69edb51e44b8.jpg align="center")

> lets have variables A and B and variable a an object and b is null, what happens when i will assign a = b,

The reference of a will copied into b (this is an imp feature of reference type)

![](https://cdn.hashnode.com/uploads/covers/6884d13c04655ac461ea86d5/ebbebcc1-1d14-4008-a2d2-3396134b6021.jpg align="center")

> what happens when i will compare a and b?

they are two different variables that refers same object on the heap  
well in this scenario these two will equal...

![](https://cdn.hashnode.com/uploads/covers/6884d13c04655ac461ea86d5/8bbf750a-e79b-4a55-94a6-9e087cf0400d.jpg align="center")

> wait  
> what what happens when i will compare a and b having 2 object in heap with identical data.?

so in this scenario it will not consider as equal, because the references are diffrent.

*   Reference types can be set to the null value.
    
*   Reference types store a reference to their value.
    
*   And this value is always stored on the heap.
    
*   Reference types can exist on the stack and on the heap, but their value is always stored on the heap.
    
*   Reference types are assigned by reference, meaning the reference is copied over.
    
*   Reference types are compared by reference to variables referring to the same object are considered equal.
    
*   And two variables referring to separate but identical objects are considered not equal.
    

## Boxing and Unboxing

Boxing and Unboxing is a process to convert value type to reference type like  
int is value type convert as object

```csharp
int number = 10;      // value type (stored in stack)
object obj = number;  // boxing
int number2 = (int)obj  //unboxing
```

what will happen here ? as respect of Memory

Boxing is the process of taking value types on the stack, packing them into objects and placing these objects on the heap. Boxing happens whenever you assign a value type to a variable parameter field or property of type object.

Unboxing is the reverse process. Objects on the heap are unpacked and the value types inside are copied back to the stack. Unboxing happens whenever you have an object value and you cast it to a value type.

![](https://cdn.hashnode.com/uploads/covers/6884d13c04655ac461ea86d5/b58164a8-574b-4e61-b178-376ab1f2c145.jpg align="center")

  
<mark class="bg-yellow-200 dark:bg-yellow-500/30">This article focused on building strong fundamentals of .NET Garbage Collection.</mark>

> <mark class="bg-yellow-200 dark:bg-yellow-500/30">In upcoming articles, we will go deeper into:</mark>
> 
> <mark class="bg-yellow-200 dark:bg-yellow-500/30">• Generational GC architecture and allocation behavior • Finalization lifecycle and Dispose pattern • GC pauses, Large Object Heap and performance tuning strategies • Real-world memory optimization techniques used in production systems</mark>

**<mark class="bg-yellow-200 dark:bg-yellow-500/30">Follow the series to continue the deep dive.</mark>**
