直接回答:sync.Pool 是 Go 提供的临时对象池:Get 取一个、Put 还一个,取不到时调 New 构造。它的价值是复用对象、摊薄分配压力、降低 GC 扫描负担——高频路径上反复创建的大对象(缓冲区、序列化中间态、解析器状态)是最佳候选。典型用户:bytes.Buffer 池、fmt 内部、JSON 编码器。
展开解析:工作机制有两个要点。其一,Pool 内部按 P(调度器处理器)分片,每个 P 有本地私有区和共享区,同 P 上 Get/Put 无锁,跨 P 窃取才走慢路径——这把竞争压到最低。其二,Pool 里的对象不保证存活:GC 发生时会清空 victim cache 之外的缓存,所以 Pool 只能放"重建成本可接受的临时对象",绝不能放连接、句柄这类有状态资源(那是连接池的活)。实践纪律:Put 回去的对象必须重置状态(buffer.Reset()),否则脏数据串到下一个使用者;对象要大小相近,避免巨型对象常驻被频繁重建。错误用法是把 Pool 当通用缓存指望命中率——它随时可能被 GC 清掉,语义就是"尽力复用"。
追问方向:Pool 为什么按 P 分片而不是按 M?victim cache 是什么?为什么不放数据库连接?
(约 420 字)