- Published on
- 🍵 4 min read
Garbage Collection: .NET vs Go
- Authors
- Name
- Emin Vergil
- @eminvergil
Overview
- Introduction
- .NET Garbage Collection
- How it works:
- Advantages of Generational GC:
- Additional .NET GC Features:
- Go Garbage Collection
- Key Differences
Introduction
Both .NET and Go employ automatic memory management through garbage collection (GC), but their approaches differ significantly.
TL;DR
Both .NET and Go use garbage collection. .NET has a generational system with 3 levels, while Go uses a simpler mark-and-sweep method. .NET is more customizable, but Go usually has shorter pause times.
.NET Garbage Collection
.NET uses a generational, mark-and-compact collector:
Generational Garbage Collection in .NET
.NET's garbage collector is based on the generational hypothesis, which states that most objects have short lifetimes. The GC divides objects into three generations:
- Generation 0 (Gen 0):
- The youngest generation.
- All new objects start here.
- Collected most frequently.
- Very fast and efficient for short-lived objects.
- Generation 1 (Gen 1):
- Objects that survive a Gen 0 collection are promoted here.
- Serves as a buffer between short-lived and long-lived objects.
- Collected less frequently than Gen 0.
- Generation 2 (Gen 2):
- The oldest generation.
- Contains long-lived objects.
- Collected least frequently.
- Full collection of Gen 2 is the most expensive operation.
How it works:
- When Gen 0 fills up, a garbage collection is triggered.
- If objects in Gen 0 survive, they're moved to Gen 1.
- If Gen 1 fills up, both Gen 0 and Gen 1 are collected.
- Objects surviving from Gen 1 are moved to Gen 2.
- When Gen 2 fills up, a full garbage collection occurs (all generations).
Advantages of Generational GC:
- Efficient for applications with many short-lived objects.
- Reduces the work done in most collections by focusing on younger generations.
- Allows for different collection strategies for different generations.
Additional .NET GC Features:
- Mark-and-Compact: Live objects are marked and compacted to reduce fragmentation.
- Concurrent: Recent versions support background GC to minimize pauses.
- Workstation vs. Server: Different GC strategies for different application types.
.NET's GC is highly tunable, with options for concurrent, background, and incremental collection.
Go Garbage Collection
Go employs a concurrent, tri-color mark-and-sweep collector:
- Concurrent: GC runs concurrently with the application, reducing pause times.
- Non-generational: All objects are treated equally, regardless of age.
- Mark-and-Sweep: Live objects are marked; unmarked objects are swept (freed).
- Write Barrier: Ensures consistency during concurrent collection.
Go's GC prioritizes low latency over maximum throughput, aiming for sub-millisecond pause times.
Key Differences
- Generational Approach: .NET uses generations, Go doesn't.
- Compaction: .NET compacts memory; Go doesn't, potentially leading to fragmentation.
- Tuning: .NET offers more tuning options; Go's GC is simpler with fewer knobs.
- Pause Times: Go generally achieves shorter pause times.
- Memory Overhead: .NET's GC can use more memory due to its generational nature.
Both systems continue to evolve, with ongoing research and improvements focused on reducing pause times and improving overall performance.
Comparison
Feature | .NET | Go |
---|---|---|
Collection Type | Generational Mark-and-Compact | Non-generational Mark-and-Sweep |
Concurrency | Concurrent and Background GC | Fully Concurrent |
Generations | 3 (Gen 0, 1, 2) | None |
Memory Compaction | Yes | No |
Tuning Options | Many | Few |
Pause Times | Can be longer, especially for Gen 2 | Generally shorter (sub-millisecond) |
Memory Overhead | Higher due to generations | Lower |
Fragmentation | Less likely due to compaction | More likely |
Primary Optimization | Throughput | Low latency |
Workstation vs Server | Different strategies available | Single strategy for all deployments |