go 临时对象池sync.Pool

sync.Pool是go标准库中的同步工具,可被称为临时对象池。属于结构体类型,值在使用之后,就不应该再被复制。

临时对象:不需要持久使用的某一类值,这类值对程序来说,可有可无。创建和销毁可有在任何时候发生,完全不影响程序功能。

可以使用临时对象池当作某种数据的缓存。

sync.Pool只有两个方法:

put:在当前的临时对象池中存放临时对象

get:从当前的临时对象池中获取临时对象。先从临时对象池删除值,再把这个值返回。如果当前池中没有任何值,这个方法会返回当前临时对象池的New字段创建一个新值,并直接将其返回。

sync.Pool的New字段代表创建临时对象函数。如果get方法到了最后也没有任何值返回,就会调用该New函数。该函数的结果并不会存入当前的临时对象池,而是直接返回给get方法的调用者。

New字段的实际值需要我们在初始化临时对象池的时候给定,否则在调用get的时候会返回nil。

为什么说临时对象池中的值会被及时清理掉?

因为go运行时系统的gc,所有每次开始执行之前,都会对所有已创建的临时对象池中的值进行全面清除

sync包在被初始化的时候,会向go语言运行时系统注册一个函数,这个函数的功能就是清除所有已创建的临时对象池中的值。可以成为池清理函数,一旦池清理函数被注册到了go语言运行时系统。运行时系统在每次即将执行垃圾回收的时候就会执行池清理函数。

在sync包中还存在一个包级私有的全局变量,这个变量代表了当前程序中使用的所有临时对象池的汇总,是元素类型为*sync.Pool的切片,可以称为池汇总表。

在临时对象池的put或者get第一次被调用的时候,这个池就会被添加到池汇总列表。正因为如此,池清理函数总是能访问到所有正在被真正使用的临时对象池。

更确切的说,池清理函数会遍历池汇总列表,对其中的每一个临时对象池,都会先将池中所有的私有临时对象和共享临时对象列表都置为nil,然后再把这个池中的所有池列表都销毁。

最后,池清理函数会把池汇总列表置为空的切片。这样,这些池中存储的临时对象就被全部清除了。如果临时对象池以外的代码再无对他们的引用,那么在稍后的gc中,就会被销毁,占用的内存空间也会被回收。

猜你喜欢

转载自blog.csdn.net/u010918487/article/details/85694216