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
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
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)
Generation 1 (Intermediate)
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
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
2. Server GC
Background Garbage Collection
.NET Core supports background GC for better performance.
Large Object Heap (LOH)
Objects larger than 85,000 bytes are stored in the Large Object Heap.
Key Points
When Does Garbage Collection Run?
GC runs automatically when:
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.