Understanding Go's Garbage Collection: Memory Management, Algorithms, and Evolution
This article explains Go's memory management by detailing stack and heap differences, describing classic and modern garbage‑collection algorithms, tracing the evolution of Go's GC from version 1.3 to 1.8, and outlining a complete GC cycle with practical code examples.
The article begins by introducing Go's memory model, distinguishing stack memory—managed by the compiler with fast allocation and automatic deallocation—from heap memory, which is managed by the runtime garbage collector and requires escape analysis to determine allocation sites.
It presents a Go struct example of a goroutine's stack layout:
type g struct{
stack stack // goroutine 使用的栈
// 下面两个成员用于栈溢出检查,实现栈的自动伸缩,抢占调度也会用到 stackguard0
stackguard0 uintptr
stackguard1 uintptr
...
}A simple program demonstrates stack‑to‑heap allocation and how the GC eventually frees heap objects:
package main
import "fmt"
type Data struct{
value int
}
func createData() *Data{
// 在堆上分配 Data 对象
data := &Data{value: 42}
// 返回指向 Data 对象的指针
return data
}
func main(){
// createData 函数返回的指针指向堆上的 Data 对象
d := createData()
// 打印指针指向的值
fmt.Println(d.value)
}The article then surveys several garbage‑collection algorithms, including reference counting (with its incremental nature and inability to handle cycles), the classic mark‑and‑sweep method (its simplicity and STW pauses), copying collection (young‑generation focus and memory overhead), and generational collection (optimizing for object lifetimes).
Next, it traces the historical development of Go's GC: Go 1.3 used a pure mark‑and‑sweep approach with full STW pauses; Go 1.5 introduced concurrent three‑color marking with insert write barriers, still requiring a final STW to rescan the stack; Go 1.8 added a hybrid write‑barrier that marks stack objects as black early, eliminating the need for stack rescan and further reducing STW time.
A complete GC cycle is broken down into three phases: an initial STW phase that pauses all goroutines and marks stack roots black, a concurrent marking phase that processes gray objects and records reference updates via the hybrid write barrier, and a concurrent sweeping phase that frees unmarked (white) heap objects and updates free‑list structures.
Finally, the article concludes that modern Go GC implementations have reduced STW pauses to sub‑millisecond levels through incremental improvements, better memory‑management strategies, and more efficient data structures, with future work aimed at further minimizing pause times.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
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.