Golang 之 sync.Pool 对象池对象重用机制总结
对象重用机制。为了减少 GC。sync.Pool 是可伸缩的,并发安全的。
两个结构体
type Pool struct {
local unsafe.Pointer // local fixed-size per-P pool, actual type is [P]poolLocal
localSize uintptr // size of the local 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 poolLocal struct {
private interface{} // Can be used only by the respective P.
shared []interface{} // Can be used by any P.
Mutex // Protects shared.
pad [128]byte // Prevents false sharing.
}
Pool 是提供外部使用的对象。Pool 有两个重要的成员。local 是一个 poolLocal 数组。localSize 是工作线程的数量 (runtime.GOMAXPROCS(0))。Pool 为每个线程分配一个 poolLocal 对象
写入和读取
Pool.Get
先获取当前线程私有值 (poolLocal.private) 获取
否则则从共享列表 (poolLocal.shared) 获取
否则则从其他线程的共享列表获取
否则直接通过 New() 分配一个返回值
Pool.Put
当前线程私有制为空。赋值给私有值
否则追加到共享列表
sync.Pool 注意点
临时性。当发生 GC 时。Pool 的对象会被清除。并且不会有通知,
无状态。当前线程中的 PoolLocal.shared 的对象可能会被其他线程偷走
大规模 Goroutine 的瓶颈
会对垃圾回收(gc) 造成负担。需要频繁的释放内存,
虽然 goroutine 只分配 2KB。但是大量 gorotine 会消耗完内存。并且 gc 也是 goroutine 调用的
原理和作用
原理类似是 IO 多路复用。就是尽可能复用。池化的核心优势就在于对 goroutine 的复用。此举首先极大减轻了 runtime 调度 goroutine 的压力,其次,便是降低了对内存的消耗
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Protobuf 入门教程
下一篇: MyBatis 介绍和使用
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论