ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Go-sync-Pool对象池最佳实践与源码分析

Go-sync-Pool对象池最佳实践与源码分析 Go-sync-Pool对象池最佳实践与源码分析文章导语sync.Pool是Go性能优化的利器能显著降低GC压力。但它的池中对象随时可能被清理特性让很多开发者困惑。本文深入Pool的源码实现和最佳使用模式。一、Pool的底层结构typePoolstruct{noCopy noCopy local unsafe.Pointer// [P]poolLocallocalSizeuintptrvictim unsafe.Pointer// 上一轮的localvictimSizeuintptrNewfunc()interface{}}typepoolLocalstruct{poolLocalInternal pad[128-unsafe.Sizeof(poolLocalInternal{})%128]byte// 防止伪共享}typepoolLocalInternalstruct{privateinterface{}// 仅当前P访问无锁shared poolChain// 当前P pushHead/popHead其他P popTail}二、GC与对象清理// GC时poolCleanup被调用// 将local移到victim清空local// 下次GC前先从victim获取// 下次GC时清空victim关键理解Pool中的对象最多存活两轮GC。第一轮从local移到victim第二轮清空victim。三、使用最佳实践// 1. Put前重置对象buf:pool.Get().(*bytes.Buffer)deferpool.Put(buf)buf.Reset()// 必须在Put前重置// 2. 不要假设Get返回的对象已初始化funcGetBuf()*bytes.Buffer{buf:bufPool.Get().(*bytes.Buffer)returnbuf// 可能包含上次的数据}// 3. Pool适合临时对象不适合持久化对象// 错误将DB连接放Pool// 正确连接池用专门的连接池库四、全文总结私有对象(private)无锁访问速度最快shared队列支持跨P窃取对象在两轮GC后一定被清理Put前必须ResetGet后必须初始化参考文献Go源码 sync/pool.goGo Blog - Using sync.PoolDave Cheney - sync.Pool
返回列表