Design and Implementation of Go's Garbage Collector
This article provides an in‑depth overview of Go's garbage collector, covering its design principles, mark‑sweep algorithm, tri‑color abstraction, write‑barrier techniques, incremental and concurrent collection, evolution across Go versions, and detailed implementation details of marking, sweeping, and memory reclamation.
The article introduces the Go runtime's garbage collector (GC), explaining that beyond allocating heap memory, a GC is required to reclaim unused objects. It outlines the historical evolution of Go's GC from a simple stop‑the‑world (STW) collector in v1.0 to the sophisticated concurrent, tri‑color, and incremental collector used today.
Design Principles
Go's GC uses a classic mark‑sweep algorithm with a tri‑color abstraction (white, gray, black) to track object reachability. The collector starts by marking root objects, then repeatedly processes gray objects, turning them black and marking their children gray, before finally sweeping unmarked (white) objects.
Mark‑Sweep Algorithm
The basic two‑phase process consists of:
Mark phase – traverse reachable objects and color them black.
Sweep phase – reclaim memory occupied by white objects.
Tri‑Color Invariant
To reduce pause times, Go maintains the tri‑color invariant using write barriers. Two variants are combined into a mixed write barrier :
writePointer(slot, ptr):
shade(*slot)
if current stack is grey:
shade(ptr)
*slot = ptrThis ensures that any pointer update during concurrent marking preserves the invariant, preventing dangling pointers.
Incremental and Concurrent Collection
Go splits GC work into small time slices, allowing the mutator (application) to run concurrently. The runtime launches background mark workers per processor, classified into three modes: gcMarkWorkerDedicatedMode – dedicated GC workers. gcMarkWorkerFractionalMode – workers that run only when GC CPU utilization is below the target. gcMarkWorkerIdleMode – workers that run when the processor is idle.
Background Mark Worker
func gcBgMarkWorker(_p_ *p) {
// ... park and wake logic ...
for {
gopark(...)
// select work based on gcMarkWorkerMode
gcDrain(&_p_.gcw, flags)
}
}Work Pool
Mark work is stored in a per‑processor gcWork structure with two buffers (wbuf1, wbuf2). Workers pull objects from the local buffer, steal from the global pool when empty, and push newly discovered gray objects back.
Scanning Objects
func gcDrain(gcw *gcWork, flags gcDrainFlags) {
// loop over work buffer, call scanobject on each gray object
// respect preemption, idle, and fractional modes
}Pause and Resume
GC pauses the world using runtime.stopTheWorldWithSema, which preempts all processors, then resumes with runtime.startTheWorldWithSema. During the pause, root scanning and initial marking are performed.
Assist Marking
When a goroutine allocates memory during the concurrent mark phase, it may need to help the collector. Each goroutine tracks gcAssistBytes. If the assist balance goes negative, the goroutine performs assist work:
func gcAssistAlloc(gp *g) {
// compute debt, possibly steal from global credit
// call gcDrainN to perform marking work
}If the global credit is insufficient, the goroutine parks and waits for background workers.
Mark Termination
When all work queues are empty, runtime.gcMarkDone signals the end of marking, disables write barriers, wakes assisting goroutines, and transitions to the _GCmarktermination phase.
Memory Reclamation
After marking, the sweep phase reclaims memory. The function runtime.sweepone iterates over spans, frees completely white spans, and returns reclaimed pages:
func sweepone() uintptr {
// pop a span, check sweepgen, call s.sweep()
// update reclaim credit
}Conclusion
The Go garbage collector combines classic algorithms with modern techniques—tri‑color marking, mixed write barriers, incremental and concurrent collection, and assist marking—to achieve low‑latency pauses (often sub‑millisecond) while maintaining high throughput. The article provides source links for deeper exploration.
Further Reading
Garbage Collection In Go : Part I - Semantics
Getting to Go: The Journey of Go's Garbage Collector
The Garbage Collection Handbook
Immix: A Mark‑Region Garbage Collector with Space Efficiency, Fast Collection, and Mutator Performance
Go’s march to low‑latency GC
GopherCon 2015: Rick Hudson - Go GC: Solving the Latency Problem
Go GC: Latency Problem Solved
Concurrent garbage collection
Design and Implementation of a Comprehensive Real‑time Java Virtual Machine
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
