Go Sync.Pool作用及遇到的坑

栏目: IT技术 · 发布时间: 5年前

内容简介:Go版本1.13.1Go中有sync.Pool类型,我们可以把它理解成存放临时值的容器,之所以加上“临时”两个字,是因为它会在GC过程的STW步骤被清理。sync.Pool类型使用前可以给它的New字段赋值,New字段类型是func() interface{},一个函数类型,该函数一般在池内为空的时候才会调用

Go版本1.13.1

Go中有sync.Pool类型,我们可以把它理解成存放临时值的容器,之所以加上“临时”两个字,是因为它会在GC过程的STW步骤被清理。

sync.Pool类型使用前可以给它的New字段赋值,New字段类型是func() interface{},一个函数类型,该函数一般在池内为空的时候才会调用

sync.Pool有两个公开的方法,一个Put,一个Get,作用看函数名就知道了

Go的并发模型是GMP模型,sync.Pool给每个P都建立了本地池,一个本地私有池,一个本地共享池,执行Get方法时,先从本地私有池取,取不到,去本地共享池,再取不到,去其他P的共享池中取,失败的话去victim cache中取,再失败就调用New方法,New生成的对象不会放到本地池中,是直接返回给调用方的。

我今天在书上发现一个“坑”,其实是 go 版本的问题导致的,书中的例子大概是这样的

package main

import (
    "fmt"
    "runtime"
    "runtime/debug"
    "sync"
    "sync/atomic"
)

var (
    count int32
    initFunc = func() interface{} {
        return atomic.AddInt32(&count, 1)
    }

    pool = sync.Pool{New:initFunc}

)
func main() {
    debug.SetGCPercent(debug.SetGCPercent(-1))

    v1 := pool.Get()
    fmt.Printf("value 1: %v\n", v1)
    pool.Put(10)
    pool.Put(11)
    pool.Put(12)
    v2 := pool.Get()
    fmt.Printf("value 2: %v\n", v2)

    runtime.GC()

    v3 := pool.Get()
    fmt.Printf("value 3: %v\n", v3)
    pool.New = nil
    v4 := pool.Get()
    fmt.Printf("value 4: %v\n", v4)
}
// 书中的输出结果
value 1: 1
value 2: 10
value 3: 2
value 4: <nil>

// 我实际的输出结果
value 1: 1
value 2: 10
value 3: 11
value 4: 12

例子里是想展示GC时会清空Pool里面的元素,清空后会调用New方法

我实际执行发现结果和书上的不一样,我当时在想怎么会出现这种情况,难道GC有问题?后来经过翻看源码,查看GC日志,发现一个关键的代码段,sync.Pool在STW时会执行poolCleanup函数

func poolCleanup() {
    // Drop victim caches from all pools.
    for _, p := range oldPools {
        p.victim = nil
        p.victimSize = 0
    }

    // Move primary cache to victim cache.
    for _, p := range allPools {
        p.victim = p.local
        p.victimSize = p.localSize
        p.local = nil
        p.localSize = 0
    }
    oldPools, allPools = allPools, nil
}

问题就出现在上面这个函数中,我这个版本的go,sync.Pool在GC时,数据会转到victim里面,也就是说会幸存一次GC,所以要实现书中的效果,需要两次GC。

后面去查看go代码提交日志,确实发现了这个代码的 提交记录

总结

总结一下sync.Pool的两个特性

  1. 对垃圾回收友好
  2. 可以把对象值产生的存储压力进行分摊

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Database Design and Implementation

Database Design and Implementation

Edward Sciore / Wiley / 2008-10-24 / 1261.00 元

* Covering the traditional database system concepts from a systems perspective, this book addresses the functionality that database systems provide as well as what algorithms and design decisions will......一起来看看 《Database Design and Implementation》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具