Introduction
In the previous article, we learned that the .NET Garbage Collector (GC) automatically removes unused objects from memory. But one important question remains:
Does the Garbage Collector scan every object in memory every time it runs?
If it did, large applications with millions of objects would become slow and inefficient.
To solve this problem, .NET uses an intelligent strategy called Generational Garbage Collection. Instead of treating every object equally, the Garbage Collector groups objects based on their age. Most newly created objects are short-lived, while only a few survive for a long time.
In this article, you'll learn what Generation 0, Generation 1, and Generation 2 are, why they exist, how objects move between them, and how this design improves the performance of .NET applications.
![gc 02]()
Why Does .NET Use Generations?
Research shows that most objects created by an application live for only a short time.
For example:
Temporary strings
API request objects
Local collections
Validation objects
Temporary DTOs
These objects are often created, used, and discarded within milliseconds.
On the other hand, objects such as:
remain alive for much longer.
Instead of checking every object during every garbage collection cycle, .NET focuses on the newest objects first. This makes memory cleanup much faster.
What Are Garbage Collection Generations?
The managed heap is divided into three logical generations:
| Generation | Description |
|---|
| Generation 0 (Gen 0) | Newly created objects |
| Generation 1 (Gen 1) | Objects that survived one collection |
| Generation 2 (Gen 2) | Long-lived objects that survived multiple collections |
Think of generations as age groups rather than separate memory areas.
How Objects Move Between Generations
Every new object starts its journey in Generation 0.
If the object is no longer needed during a garbage collection, it is removed.
If it is still being used, it survives and moves to the next generation.
The process continues until the object eventually becomes unreachable and is collected.
Internal Flow
Create Object
│
▼
Generation 0
│
├── Not Referenced
│ │
│ ▼
│ Removed by GC
│
▼
Still Referenced
│
▼
Generation 1
│
├── Not Referenced
│ │
│ ▼
│ Removed by GC
│
▼
Still Referenced
│
▼
Generation 2
│
▼
Removed when no longer reachable
Understanding Generation 0
Generation 0 contains all newly created objects.
Example:
Employee employee = new Employee();
When this object is created, it is placed in Generation 0.
Generation 0 is collected most frequently because most temporary objects become unused very quickly.
Examples include:
Temporary strings
Method variables
Request objects
DTOs
LINQ query results
Since Gen 0 contains many short-lived objects, collections are usually fast.
Understanding Generation 1
Generation 1 acts as a bridge between short-lived and long-lived objects.
Objects reach Gen 1 only if they survive a Gen 0 collection.
These objects have lived longer than expected but are not yet considered long-lived.
Examples:
Generation 1 is collected less often than Generation 0.
Understanding Generation 2
Generation 2 stores objects that have survived multiple garbage collections.
These objects usually remain in memory for a long time.
Examples include:
Since Gen 2 often contains many important objects, collections are more expensive and happen less frequently.
Visual Journey of an Object
Application Starts
│
▼
Create Employee Object
│
▼
Generation 0
│
▼
Still Needed?
Yes ─────────► Generation 1
│
▼
Still Needed?
Yes ─────────► Generation 2
│
▼
Reference Removed
│
▼
Garbage Collector Removes Object
Practical Example
class Employee
{
public string Name { get; set; }
}
Employee employee = new Employee();
employee.Name = "Ajay";
Initially:
Generation 0
Suppose the object is still needed after the first garbage collection.
It moves to:
Generation 1
If it continues to be referenced for a longer period, it is promoted again.
Generation 2
Eventually:
employee = null;
Once no references remain, the Garbage Collector removes the object during an appropriate collection cycle.
What About the Large Object Heap (LOH)?
Most objects are stored in the normal managed heap.
However, very large objects (typically 85 KB or larger) are allocated in a separate area called the Large Object Heap (LOH).
Examples include:
Large byte arrays
Large image buffers
Large collections
The LOH is managed differently because moving very large objects frequently would reduce performance.
We'll explore the Large Object Heap and its performance considerations in more detail in a later article.
Common Mistakes
Thinking objects are manually assigned to generations
Developers never choose the generation. The .NET runtime automatically manages object promotion.
Assuming Generation 2 is "better"
Generation 2 simply means an object has lived longer. It does not indicate higher importance or better performance.
Believing all generations are collected together
Most garbage collection cycles target only Generation 0. Gen 1 and Gen 2 are collected less frequently to improve performance.
Assuming promotion happens immediately
Objects move to a higher generation only after surviving a garbage collection.
Best Practices
Allow the Garbage Collector to manage object generations automatically.
Avoid creating unnecessary temporary objects in performance-critical code.
Reuse objects where appropriate to reduce allocation pressure.
Don't force collections using GC.Collect() unless there is a specific, well-understood reason.
Focus on writing clean, maintainable code rather than trying to manipulate generations.
Key Takeaways
Every new object starts in Generation 0.
Objects that survive a collection are promoted to higher generations.
Generation 0 is collected most frequently.
Generation 2 contains long-lived objects and is collected less often.
The generational design significantly improves the performance of .NET applications by avoiding unnecessary scans of long-lived objects.
Developers do not manually control object generations; the CLR manages the entire lifecycle.