golang中的sync.Pool对象缓存

参考文章

知识点

  • golang1.13版本对Pool进行了优化,结构体添加了两个字段 victim 和 victimSize。
  • 适应于通过复用,降低复杂对象的创建和GC代价的场景
  • 每个sync.Pool的生命周期为两次GC中间时段才有效,因为init()的时候会注册一个PoolCleanup函数,他会在gc时清除掉sync.Pool中的所有的缓存的对象。可以手动进行gc操作 runtime.GC()
  • 由于生命周期受GC的影响,一定不要用于数据库连接池这类的应用场景,它只是一个缓存。
  • 由于要保证协程安全,所以会有锁的开销
  • 每个Pool都有一个私有池(协程安全)和共享池(协程不安全),其中私有池只有存放一个值。
    1. 每次Get()时会先从当前P的私有池private中获取(MPG模型
    2. 如果获取失败,再从当前P的共享池share中获取
    3. 如果仍失败,则从其它P中共享池中拿一个,需要加锁保证协程安全
    4. 如果还失败,则表示所有P中的池(也有可能只是共享池)都为空,则需要New()一个并直接返回(此时不会被放入池中)
    每次取值出来后,会从原来的地方删除掉该值。