美文网首页
sync.Pool 源码解读- note

sync.Pool 源码解读- note

作者: robertzhai | 来源:发表于2023-02-20 08:20 被阅读0次
    type Pool struct {
        noCopy noCopy
    
        local     unsafe.Pointer // local fixed-size per-P pool, actual type is [P]poolLocal
        localSize uintptr        // size of the local array
    
        victim     unsafe.Pointer // local from previous cycle
        victimSize uintptr        // size of victims array
    
        // New optionally specifies a function to generate
        // a value when Get would otherwise return nil.
        // It may not be changed concurrently with calls to Get.
        New func() interface{}
    }
    
    // Local per-P Pool appendix.
    type poolLocalInternal struct {
        private interface{} // Can be used only by the respective P.
        shared  poolChain   // Local P can pushHead/popHead; any P can popTail.
    }
    
    type poolLocal struct {
        poolLocalInternal
    
        // Prevents false sharing on widespread platforms with
        // 128 mod (cache line size) = 0 .
        pad [128 - unsafe.Sizeof(poolLocalInternal{})%128]byte
    }
    

    sync.Pool 的特性

    • 池不能够指定大小,大小只受限于 GC 的临界值(GOMAXPROCS)
    • 对象最大的缓存周期是两个 GC 周期,每次 GC ,当前的 primary cache 会被转移到 victim cache,primary cache 清空,而原来 victim cache 被释放
    • 取值顺序:当前 P 的 primary cache(local)的 poolLocal.private → 当前 P 的 primary cache(local)的 poolLocal.shared.head → 其他 P 的主存(local)的 poolLocal.shared.tail → 当前 P 的 victim cache(victim) 的 poolLocal.private → 当前 P 的 victim cache(victim) 的 poolLocal.shared.head → 其他 P 的主存(local)的 poolLocal.shared.tail → p.New() → nil
    • 插入顺序:当前 P 的 primary cache(local)的 poolLocal.private → 当前 P 的 primary cache(local)的 poolLocal.shared.head

    sync.pool拿取缓存的过程

    • 一个goroutine会抢占p,然后首先从当前p的private 中选择对象,如果里面没找到,然后尝试本地p的shared 队列的队头进行读取,若还是取不到,则尝试从其他 P 的 shared 队列队尾中偷取。 若偷不到,则尝试从上一个 GC 周期遗留到 victim 缓存中取,否则调用 New 创建一个新的对象。

    • 对于回收而言,池中所有临时对象在一次 GC 后会被放入 victim 缓存中, 而前一个周期被放入 victim 的缓存则会被清理掉。

    • 在加入 victim 机制前,sync.Pool 里对象的最⼤缓存时间是一个 GC 周期,当 GC 开始时,没有被引⽤的对象都会被清理掉;加入 victim 机制后,最大缓存时间为两个 GC 周期。

    • 当get一个对象使用完成之后,调用put归还的时候,需要注意将里面的内容清除

    • Pool 不可以指定⼤⼩,⼤⼩只受制于 GC 临界值。

    相关文章

      网友评论

          本文标题:sync.Pool 源码解读- note

          本文链接:https://www.haomeiwen.com/subject/bydwkdtx.html