首页 > 其他分享 >golang sync.Pool 的基本原理

golang sync.Pool 的基本原理

时间:2024-07-11 11:42:25浏览次数:16  
标签:Get 对象 sync golang 并发 GC Pool

sync.Pool 包寥寥不过300行代码,却可以为我们提供类似对象池的功能,减少了对象的重复创建于销毁,减少了性能损耗,增加内存复用,同时自带 mutex 锁可以保证 Put/Get 操作的并发安全特性,在一些对象需要重复创建销毁的场景中很是实用,今天来看看 sync.Pool 的基本原理。

sync.Pool 就在标准库中,注释开篇就是:

// A Pool is a set of temporary objects that may be individually saved and
// retrieved.
//
// Any item stored in the Pool may be removed automatically at any time without
// notification. If the Pool holds the only reference when this happens, the
// item might be deallocated.
//
// A Pool is safe for use by multiple goroutines simultaneously.

翻译过来就是:

1.对象池是提供一种存储、获取临时对象的集合
2.不要把对象池当做缓存来处理,因为任何存储的对象,在某个时刻都可能会被回收掉,而且没有任何通知的情况下
3.这个对象池的使用是并发安全的

继续往下看:

// Pool's purpose is to cache allocated but unused items for later reuse,
// relieving pressure on the garbage collector. That is, it makes it easy to
// build efficient, thread-safe free lists. However, it is not suitable for all
// free lists.
//
// An appropriate use of a Pool is to manage a group of temporary items
// silently shared among and potentially reused by concurrent independent
// clients of a package. Pool provides a way to amortize allocation overhead
// across many clients.

翻译过来:

1.对象池的目的是用来缓存那些已分配但是在后续的重复使用的对象,可以减轻GC压力
2.对象池一种合适的使用场景,是在多个客户端之间共享重用对象,得以分摊内存分配的开销

后面的注释也提到,其实在 fmt 包中也是有 Pool 使用的体现,内部维护了一个动态大小的临时输出 buffer 空间。

需要注意的点:

1.短生命周期的对象不太适合放对象池中
2.对象池不要复制
3.一般的使用场景,先声明 New(),然后再去使用 Get()/Put() 方法,可以 put 任何对象,但在 get 对象的时候,需要用到断言,即 Get().(Type)
4.对象池中的对象数量不能做任何假设,什么时候新建什么时候被GC,这些都是不确定的,对象池主要是能尽可能复用对象,减少GC
5.Pool本身的数据结构是并发安全,但是 Pool.New() 方法需要使用者注意场景使用,如并发下,则加上并发安全策略,如原子操作或者加互斥锁等

标签:Get,对象,sync,golang,并发,GC,Pool
From: https://www.cnblogs.com/davis12/p/18295610

相关文章

  • Redis中设置增量缓存,减少对数据库的交互查询;启动@Async;异步线程
    //当属于这个分支的报文传入调用processMessage方法if((newJSONObject(dataMessage).optString("documentStatus")).equals("carWeizi_redis_service")){processMessage(dataMessage);}//processMessage中先把增量数据插入数据库,同时缓存redispublic......
  • rsync
    rsync与inotify【1】、rsync同步操作应用场景(业务场景)应用建议rsync作为命令使用临时拉取,推送数据。未来这和需求可以通过scp命令实现定时备份:rsync服务+定时任务定时备份,定期备份(定时任务进行备份+通过rsync传输备份)实时同步:rsync服务+sersync/lsyncd是先试试......
  • mormot.core.threads--TSynThreadPool
    mormot.core.threads--TSynThreadPool{************面向服务器进程的线程池}TSynThreadPool=class;//前向声明TSynThreadPool类///定义了TSynThreadPool所使用的工作线程TSynThreadPoolWorkThread=class(TSynThread)protectedfOwner:TSynThreadPool;//......
  • 【转】-synchronized与Lock的区别与使用
    详解synchronized与Lock的区别与使用该博客转载自​淳安郭富城​的​详解synchronized与Lock的区别与使用1.引言:昨天在学习别人分享的面试经验时,看到Lock的使用。想起自己在上次面试也遇到了synchronized与Lock的区别与使用。于是,我整理了两者的区别和使用情况,同时,对synchroni......
  • golang 操作es
    docker 操作安装es 1.创建网络因为我们还需要部署kibana容器,因此需要让es和kibana容器互联,这里先创建一个网络。使用FinalShell登录自己的Linux云服务器客户端(阿里云或腾讯云)dockernetworkcreatees-net2.加载镜像 dockerpulldocker.elastic.co/elasticsearc......
  • Golang 切片作为函数参数传递的陷阱与解答
    作者:林冠宏/指尖下的幽灵。转载者,请:务必标明出处。GitHub:https://github.com/af913337456/出版的书籍:《1.0-区块链DApp开发实战》《2.0-区块链DApp开发:基于公链》例子切片作为函数参数传递的是值用来误导切片作为函数参数传递的是引用函数内切片append引起......
  • [Java并发]Synchronized
    publicclassAtomicTest01{publicstaticinti=0;publicstaticvoidmain(String[]args){Runnabletask=newRunnable(){@Overridepublicvoidrun(){synchronized(this){tr......
  • golang-数组基本使用
    Go语言中的数组是一个固定长度的元素序列,这些元素都是相同的类型。数组是值类型,这意味着当它们被赋值给新的变量时,会进行一次数组的复制。创建数组通过指定元素类型和数组长度来创建数组。数组长度必须是一个常量表达式,因为数组的长度是其类型的一部分。数组的数量一旦确定就不......
  • ThreadPoolExecutor - 管理线程池的核心类
    下面是使用给定的初始参数创建一个新的ThreadPoolExecutor(构造方法)。publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnitun......
  • rsync使用教程
    1、rsync是什么rsync是一个在Unix/Linux环境下常用的工具,Windows上可以通过一些替代工具或者使用Cygwin环境来实现类似的功能。Cygwin在安装过程中,选择需要安装的组件时确保选择了rsync和openssh(如果需要通过SSH连接到其他服务器进行备份)。rsync的简单使用如下:rsync-avz......