sync.Pool适用于高频创建/销毁短生命周期小对象的场景,需正确设置New函数、手动Get/Put并重置状态,避免跨goroutine归还或Put脏数据,配合pprof和benchmark验证效果。
Go 语言中,sync.Pool 是一个轻量、线程安全的对象缓存池,专为高频创建/销毁短生命周期对象的场景设计。它不解决内存泄漏,也不保证对象一定被复用,但能显著减少堆分配次数和 GC 扫描压力——尤其在高并发、小对象(如 buffer、request context、临时结构体)频繁分配时效果明显。
适合以下典型场景:
bytes.Buffer、自定义 parser 上下文)
配 byte slice(如 JSON 解析中的临时缓冲区)go tool pprof 验证)不适合:长期持有对象、含指针/闭包/未清零字段的复杂结构、需要严格控制生命周期的资源(如 DB 连接)。
关键点是设置 New 函数,并在每次取用后手动归还:
New 必须返回**新分配且已清零/初始化**的对象(Pool 不会自动清理)Put 归还(推荐 defer)bytes.Buffer 的内容)示例:
var bufPool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
func handleRequest() {
buf := bufPool.Get().(*bytes.Buffer)
defer bufPool.Put(buf) // 必须放回
buf.Reset() // 清空内容,避免脏数据残留
buf.WriteString("hello")
// ... use buf
}
几个容易踩坑的地方:
用 go test -bench 对比启用前后指标:
BenchmarkAllocsPerOp 是否下降(越低越好)gc pause 时间是否缩短(pprof trace)示例压测片段:
func BenchmarkWithPool(b *testing.B) {
for i := 0; i < b.N; i++ {
buf := bufPool.Get().(*bytes.Buffer)
buf.Reset()
buf.WriteString("data")
_ = buf.String()
bufPool.Put(buf)
}
}