GC - 图1

内存泄漏

预期的能很快被释放的内存由于附着在了长期存活的内存上、或生命期意外地被延长,导致预计能够立即回收的内存而长时间得不到回收。

形式1:附着在全局变量

  1. var cache = map[interface{}]interface{}{}
  2. func keepalloc() {
  3. for i := 0; i < 10000; i++ {
  4. m := make([]byte, 1<<10)
  5. cache[i] = m
  6. }
  7. }

形式二:goroutine泄漏

GC的过程

当前版本的 Go 以 STW 为界限,可以将 GC 划分为五个阶段:

阶段 说明 赋值器状态
SweepTermination 清扫终止阶段,为下一个阶段的并发标记做准备工作,启动写屏障 STW
Mark 扫描标记阶段,与赋值器并发执行,写屏障开启 并发
MarkTermination 标记终止阶段,保证一个周期内标记任务完成,停止写屏障 STW
GCoff 内存清扫阶段,将需要回收的内存归还到堆中,写屏障关闭 并发
GCoff 内存归还阶段,将过多的内存归还给操作系统,写屏障关闭 并发

具体而言,各个阶段的触发函数分别为:
GC - 图2