跳到主要内容

内存与 GC 知识体系概览

问题

Go 的内存管理模型是怎样的?垃圾回收算法是什么?如何进行内存调优?

答案

Go 的内存管理是自动的——开发者不需要手动 malloc/free,由 Go 运行时的垃圾回收器(GC)自动管理。理解 Go 的内存模型对于写出高性能程序至关重要。

知识体系总览

核心知识点

1. 栈 vs 堆

特性栈(Stack)堆(Heap)
分配速度极快(移动指针)较慢(需要 GC 管理)
回收函数返回自动回收GC 回收
大小goroutine 栈初始 2KB~8KB,动态增长几乎无限
分配条件编译器确认变量不逃逸变量逃逸到堆

目标:尽量让变量分配在栈上(不触发 GC),避免不必要的堆分配。

2. 逃逸分析

编译器在编译时决定变量分配在栈还是堆。查看逃逸分析结果:

go build -gcflags="-m" main.go

常见逃逸场景:

  • 函数返回局部变量指针
  • 发送到 Channel 的指针
  • interface 参数
  • 闭包引用的变量
  • 超大对象

3. 三色标记 GC

Go 使用并发三色标记清扫算法:

  1. 初始:所有对象标记为白色
  2. 标记:从根对象开始,标记可达对象(白→灰→黑)
  3. 清扫:剩余白色对象即为垃圾,回收

通过混合写屏障(Go 1.8+)实现并发标记,STW 时间极短(通常 < 1ms)。

4. GC 调优

# GOGC 控制 GC 频率(默认 100,即堆增长 100% 时触发)
GOGC=200 ./myapp # 降低 GC 频率(减少 CPU 开销,增加内存使用)
GOGC=50 ./myapp # 提高 GC 频率(减少内存使用,增加 CPU 开销)
GOGC=off ./myapp # 关闭 GC(仅用于测试)

# Go 1.19+: GOMEMLIMIT 设置内存上限
GOMEMLIMIT=1GiB ./myapp # 限制堆内存上限为 1GB

5. pprof 内存分析

import _ "net/http/pprof"

go func() {
http.ListenAndServe("localhost:6060", nil)
}()
# 堆内存分析
go tool pprof http://localhost:6060/debug/pprof/heap

# 分配次数分析
go tool pprof -alloc_objects http://localhost:6060/debug/pprof/heap

关键分类文档导航

文档核心内容
内存模型与分配器栈/堆、TCMalloc 分配器、内存对齐
逃逸分析逃逸场景、优化策略、-gcflags 分析
GC 三色标记标记清扫算法、写屏障、STW
GC 调优GOGC、GOMEMLIMIT、GC 日志
pprof 内存分析堆分析、goroutine 分析、火焰图
内存泄漏排查常见泄漏场景、排查工具
sync.Pool 与对象复用对象池原理、使用场景
减少内存分配优化技巧、零分配模式

面试重点

高频面试问题
  1. Go 的 GC 算法是什么?STW 有多长?
  2. 什么是逃逸分析?哪些情况会逃逸?
  3. 如何用 pprof 排查内存问题?
  4. GOGC 和 GOMEMLIMIT 怎么配?
  5. Go 内存泄漏的常见场景?

相关链接