sync.Pool 是临时对象池,用于复用分配成本高的临时对象,降低 GC 压力。Get 取对象(无则调 New 构造),Put 放回。底层为每个 P 维护本地无锁队列加共享池,大部分 Get/Put 不需要加锁,扩展性好。关键特性:池中的对象在 GC 时会被无条件清空,所以 Pool 只做性能优化,绝不能当作缓存依赖其持久性。
适用场景:高频、短命、构造贵的临时对象,且复用安全(无残留状态或能重置)。标准库典型用法如 fmt 的缓冲、encoding/json 的编码状态。反例:对象有生命周期语义(连接、带状态的会话)应该用显式连接池;低频场景用 Pool 无收益。
var bufPool = sync.Pool{
New: func() any { return new(bytes.Buffer) },
}
buf := bufPool.Get().(*bytes.Buffer)
buf.Reset() // 复用前必须重置状态
defer bufPool.Put(buf)
易错点:Put 进去的对象被外部引用会导致数据错乱;Put 大尺寸对象可能长期占内存(GC 才清);Go 1.20+ 对 Pool 做了 victim cache 优化,跨 GC 存活率更好。追问方向:per-P 本地池如何避免竞争、victim 机制、与连接池的设计差异。