package main
import(
"fmt"
"sync"
)
//问题
//如果goroutine过多,可能导致对象的创建数目剧增。
//而对象又是占用内存的,进而导致的就是内存回收的GC压力徒增,GC压力过大
//上面创建了一个缓存int对象一个pool池,
//从池中获取一个对象然后放进去然后再取出来
func main() {
p := &sync.Pool{
New: func() interface{} { //src/pkg/sync/pool.go 注册时是没有限定大小的,poolCleanup
//函数会清除掉所有缓存对象,缓存期限是两次gc之间
return 0
},
}
a := p.Get().(int) //goroutine 放到 P固定的池子上,然后对池子进行操作,访问的是池子
//里面的私有对象,是不需要加锁的
//池中的共享列表是需要加锁的
//那这里另外一个问题也凸显出来了,很可能我上一步刚往pool中PUT一个对象之后,下一步GC触发,导致pool的GET函数获取不到
//PUT进去的对象。
//这个时候,GET函数就会调用New函数,临时创建出一个对象,并存放到pool中
p.Put(1)
b := p.Get().(int)
fmt.Println(a, b)
}
//问题
//但是这里可能会有一个问题,我们没有看到Pool的手动回收函数。
//那么是不是就意味着,如果我们的并发量不断增加,这个Pool的体积会不断变大,或者一直维持在很大的范围内呢?
//答案是不会的,sync.Pool的回收是有的,它是在系统自动GC的时候,触发pool.go中的poolCleanup函数
func init(){
runtime_registerPoolCleanup(poolCleanup)
}
//适用场景
//它更适合用来做临时对象池,目的是为了降低GC的
//压力。
//output 列表0 1
end.
有疑问加站长微信联系(非本文作者)