Go 的内存管理和 GC 是理解 Go 运行时行为的关键。从栈逃逸分析到 GC 触发策略,深入理解这些机制能帮助你写出更高效的 Go 代码。
逃逸分析
Go 编译器使用逃逸分析来决定变量分配在栈上还是堆上。如果变量在函数返回后仍被引用,它就"逃逸"到堆上。了解逃逸规则可以减少不必要的堆分配。
// 查看逃逸分析结果
// go build -gcflags="-m" main.go
func createUser() *User {
u := User{Name: "test"} // 逃逸到堆(返回了指针)
return &u
}
func processUser() {
u := User{Name: "test"} // 分配在栈上
doSomething(u)
}
GC 工作原理
Go 使用并发三色标记-清除算法,GC 与用户代码并发执行。关键参数:
- GOGC:GC 触发阈值,默认 100(堆增长 100% 时触发 GC)。
- GOMEMLIMIT:Go 1.19 引入的软内存限制。
减少 GC 压力
- 使用 sync.Pool 复用频繁分配的对象。
- 优先使用值类型而非指针。
- 预分配 slice 容量,避免多次扩容。
- 使用 strings.Builder 代替字符串拼接。
了解内存从哪来、到哪去,是写出高性能 Go 程序的基本功。