Go Sync.Pool作用及遇到的坑

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

内容简介: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. 可以把对象值产生的存储压力进行分摊

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

查看所有标签

猜你喜欢:

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

Unity 3D游戏开发(第2版)

Unity 3D游戏开发(第2版)

宣雨松 / 人民邮电出版社 / 2018-9 / 89.00元

Unity 是一款市场占有率非常高的商业游戏引擎,横跨25 个主流游戏平台。本书基于Unity 2018,结合2D 游戏开发和3D 游戏开发的案例,详细介绍了它的方方面面,内容涉及编辑器、游戏脚本、UGUI 游戏界面、动画系统、持久化数据、静态对象、多媒体、资源加载与优化、自动化与打包等。 本书适合初学者或者有一定基础的开发者阅读。一起来看看 《Unity 3D游戏开发(第2版)》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

MD5 加密
MD5 加密

MD5 加密工具

html转js在线工具
html转js在线工具

html转js在线工具