← 中文资源

简体中文版本

用 sync.Pool 减少 Go 内存分配

通过 sync.Pool 复用高频短生命周期缓冲,降低高吞吐路径上的 GC 压力。

阅读英文原文

目标

高吞吐处理器每次请求都分配同样的缓冲,GC 压力限制了吞吐。本配方为频繁分配的缓冲引入 sync.Pool,在取得时把切片长度重置为零并 defer 归还,从而跨请求复用;用基准对比分配次数并观察 GC 停顿下降。

步骤要点

  1. 为热路径缓冲引入 sync.Pool。
  2. 取得时把长度重置为零并 defer 归还。
  3. 用 -benchmem 对比分配次数。
  4. 限制池中缓冲大小避免保留过多内存。
var bufPool = sync.Pool{New: func() any { return make([]byte, 0, 32*1024) }}

func handle(data []byte) {
    buf := bufPool.Get().([]byte)[:0]
    defer bufPool.Put(buf)
    buf = append(buf, data...)
}

排错提示

  • 未重置会串数据,必须重置长度。
  • 池可能无界增长,需限制缓冲大小。
  • 对分配很轻的路径无帮助。

适用边界

  • 可能提高驻留内存。
  • 正确性依赖状态重置。