.NET Core  

How Does Garbage Collection Work in .NET Core?

Introduction

Memory management is one of the most important aspects of building high-performance applications in .NET Core. Instead of manually allocating and freeing memory like in some other programming languages, .NET Core provides an automatic memory management system called Garbage Collection (GC).

Garbage Collection in .NET Core helps developers focus on writing business logic without worrying about memory leaks or manual cleanup. However, understanding how garbage collection works internally is very important for writing efficient, scalable, and high-performance applications.

In this article, we will explain how Garbage Collection works in .NET Core in simple words, explore its internal process, and understand best practices with real-world examples.

What is Garbage Collection in .NET Core?

Garbage Collection (GC) is an automatic memory management system in .NET Core that removes unused objects from memory.

In simple words, GC frees up memory by deleting objects that are no longer being used by the application.

Why Garbage Collection is Important

  • Prevents memory leaks

  • Automatically manages memory allocation and deallocation

  • Improves application performance

  • Reduces developer effort

How Memory Works in .NET Core

Before understanding GC, it is important to understand how memory is structured.

.NET Core mainly uses two types of memory:

  • Stack Memory

  • Heap Memory

Stack Memory

  • Stores value types (int, double, struct)

  • Stores method calls and execution context

  • Very fast and automatically managed

Heap Memory

  • Stores reference types (objects, classes, arrays)

  • Managed by Garbage Collector

  • Slower than stack but more flexible

What Happens When You Create an Object?

When you create an object in .NET Core:

var person = new Person();
  • Memory is allocated on the heap

  • The reference is stored on the stack

  • GC keeps track of this object

Generations in Garbage Collection

.NET Core GC uses a Generational Garbage Collection system.

Objects are divided into three generations:

  • Generation 0 (Gen 0)

  • Generation 1 (Gen 1)

  • Generation 2 (Gen 2)

Generation 0 (Young Objects)

  • Newly created objects are stored here

  • Collected frequently

  • Fast cleanup

Generation 1 (Intermediate)

  • Objects that survive Gen 0 move here

  • Acts as a buffer

Generation 2 (Long-Lived Objects)

  • Objects that survive Gen 1 move here

  • Collected less frequently

  • Includes long-lived data like static objects

How Garbage Collection Works (Step-by-Step)

Step 1: Object Allocation

New objects are created in Generation 0.

Step 2: Mark Phase

GC identifies which objects are still in use (reachable objects).

Step 3: Sweep Phase

Unused (unreachable) objects are marked for deletion.

Step 4: Compact Phase

Memory is compacted to remove gaps and improve performance.

Step 5: Promotion

Surviving objects are moved to the next generation.

Important Concept: Reachable vs Unreachable Objects

  • Reachable Objects: Still being used → Not removed

  • Unreachable Objects: No references → Removed by GC

Example

Person p1 = new Person();
Person p2 = new Person();

p1 = null; // Now p1 object becomes eligible for GC

Here, the object referenced by p1 becomes unreachable and can be collected.

Types of Garbage Collection

1. Workstation GC

  • Used for desktop applications

  • Optimized for responsiveness

2. Server GC

  • Used for server applications

  • Optimized for performance and throughput

  • Uses multiple threads

Background Garbage Collection

.NET Core supports background GC for better performance.

  • Runs in the background

  • Reduces application pauses

  • Improves user experience

Large Object Heap (LOH)

Objects larger than 85,000 bytes are stored in the Large Object Heap.

Key Points

  • Not compacted frequently

  • Can impact performance if misused

  • Used for large arrays and buffers

When Does Garbage Collection Run?

GC runs automatically when:

  • Memory is low

  • Generation thresholds are reached

  • System is idle

Developers can also force GC manually (not recommended):

GC.Collect();

Best Practices for Garbage Collection in .NET Core

1. Avoid Unnecessary Object Creation

Creating too many objects increases GC pressure.

2. Use Using Statement for Resources

using (var stream = new FileStream("file.txt", FileMode.Open))
{
    // Use stream
}

3. Implement IDisposable

For unmanaged resources like files or database connections.

4. Avoid Large Object Allocations

Reuse objects when possible.

5. Do Not Force GC Frequently

Manual GC calls can degrade performance.

Real-World Example

Imagine a web application handling thousands of requests:

  • Each request creates objects

  • GC cleans unused objects automatically

  • Efficient GC ensures smooth performance

Without GC, memory would keep increasing and crash the application.

Summary

Garbage Collection in .NET Core is a powerful feature that automatically manages memory by removing unused objects. It uses a generational approach to improve performance and efficiency. By understanding how GC works, developers can write better, optimized, and scalable applications. Proper memory management techniques and best practices can significantly improve application performance and reduce memory-related issues.