热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Go学习_18_Golang的sync.Pool的对象池

Go学习_18_Golang的sync.Pool的对象池,Go语言社区,Golang程序员人脉社

Flutter、Golang、Python、编译原理、算法、Chrome原理学习系列文章抢先看请关注【码农帮派】

【Golang学习系列文章,请扫二维码】

上一节中我们通过Buffered channel实现了对象池的功能,但是我们发现在Golang的sync包中有一个Pool,sync.Pool其实是对象缓存机制。

sync.Pool的对象缓存是和Processor关联的。Processor在Golang的MPG中介绍过,M是Machine,一个M关联一个内核对象;P是协程处理器,是M运行的上下文环境;G就是协程。

对于Processor,它的数据对象如下图:

每个Processor包含一个私有对象和一个共享池,很多资料上将私有对象成为私有对象池,这是不合适的,因为它只能缓存一个对象,因此更为准确的应该是私有对象。

其中私有对象是协程安全的,共享池是协程不安全的。私有对象本身已经实现了锁,因此我们在访问私有对象的时候无需自己加锁,而共享池是协程不安全的,因此我们在使用共享池的时候是需要自己加锁的。

sync.Pool对象获取的流程:

  1. 尝试从私有对象获取

  2. 私有对象不存在,尝试从当前Processor的共享池中获取

  3. 如果当前Processor共享池也是空的,那么尝试从其他Processor的共享池中获取

  4. 如果所有子池都是空的,那么使用sync.Pool的New函数创建一个新的对象,并返回。

sync.Pool对象返回的流程:

  1. 如果私有对象不存在,则存储到私有对象中

  2. 如果私有对象已存在,则放入到当前Processor的共享池中

sync.Pool的使用方法:

pool := &sync.Pool {    New: func() interface{} {        return 0    },}
// 获取对象item := pool.Get().(int)
// 对象放回pool.Put(1)

在创建一个sync.Pool的时候,我们指定了一个New函数,保证在私有对象和每个共享池中获取不到对象的时候,可以进行对象初始化创建。

sync.Pool的生命周期

  • GC会清除sync.Pool缓存的数据对象

  • sync.Pool对象缓存的有效期为下一次GC之前

正是因为sync.Pool对象的周期会受到系统GC的影响,因此不能够被当作一种稳定的对象池来使用,只能当作对象缓存。

上面的代码中,我们首次从sync.Pool中获取对象,是通过New函数创建的,当我们使用放回函数放回一个缓存对象之后,再次获取,发现获取到的就是我们放回的对象数据。

我们在程序中手动出发一次GC:

从上面的结果可以看出,即使我们已经向sync.Pool中放回了对象,但是系统GC会将sync.Pool中的对象清空。

需要注意的是,我们首次从sync.Pool中获取对象是通过New函数创建的,我们需要将获取的对象放回到sync.Pool中,否则下次获取的时候,sync.Pool仍然是通过New函数重新创建并返回对象:

上面代码中,只有获取并没有放回,两次获取操作都触发了sync.Pool的New函数重新创建对象。

下面的代码中,我们在多协程中访问sync.Pool的对象,因为我们在协程中只获取,没有返回数据,所有后面协程获取的对象都是通过New函数创建的新对象:

sync.Pool总结:

  • sync.Pool适用于通过复用,来降低复杂对象的创建和GC的代价

  • sync.Pool协程安全的,内部实现了锁机制,会有锁的性能开销

  • sync.Pool中对象的生命周期受到GC的影响,不适合用作链接缓存池,也不适用于需要自己管理对象生命周期的对象池


推荐阅读
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了使用Python根据字典中的值进行排序的方法,并给出了实验结果。通过将字典转化为记录项,可以按照字典中的值进行排序操作。实验结果显示,按照值进行排序后的记录项为[('b', 2), ('a', 3)]。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
author-avatar
躺在地球上的熊
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有