对于一些对象,为了优化性能,节省每次使用都创建新对象所带来的内存开销,可以使用池化技术,预先创建好一些对象放入池中,使用时从池中获取,使用完再放回池中。这样就减少了对象创建所带来的开销。
在go中,原生的池化数据结构为sync.Pool, 有三个方法:
func() interface{}
, 在新建Pool时,定义好New字段,以供后续从池中获取对象时,如果当前池中无对象,则使用此方法来新建对象。使用样例:
conPool := sync.Pool{
New: func() interface{} { return &Con{age: 20} },
}
con := conPool.Get().(*Con)
fmt.Printf("con.age: %v\n", con.Age())
conPool.Put(con)
sync.Pool用于保存一组可独立访问的临时对象,注意加粗的临时,说明它池化的对象在未来某个时候会被
毫无征兆的移除掉。
go中sync.Pool的特点:
使用sync.Pool的注意点:
Pool 的另一个很常用的一个场景就是保持 TCP 的连接。
(事实上,很少用sync.Pool去池化连接对象,因为sync.Pool会无通知的将某个连接回收,因此
会其他方法来池化对象)
当使用并发任务时,我们常常建立一个任务池,控制并发时最少最多的goroutine数量。
Pool是一个通用的概念,当程序中有很多需要重复创建的对象,可以创建池类对象。