引言
在 Java 的世界中,对象的生命周期基本都是创建,使用,GC 回收。但是有些对象由于其创建的频度高,创建代价昂贵,且具备重复利用的可能性,因此往往希望将这类对象缓存起来,供后续的重复利用。这就出现了一种专门的设施结构:对象缓存池,专注于提供对象的复用,减少对象创建的开销。
在前文的很多分析中,特别是一些高频率使用的对象,比如PooledByteBuf
等,我们都能见到一个类的身影,就是Recycle
。这个类是Netty 设计的轻量级对象缓存池实现。因为像PooledByteBuf
这种对象的创建是非常频繁的,每一次数据的读取,业务流程的处理都需要承载在这个对象上。但是一旦业务处理完毕就直接被丢弃了。如果反复的创建,对系统的GC压力来说也是很大的。使用对象缓存池,可以减少频繁重复创建的开销,提升一定的性能。
思路推导
像前文一样,我们先不分析代码,从设计的角度来推导对象池可能的实现方式。
对象池简单说就是将对象实例缓存起来供后续分配使用来避免瞬时大量小对象反复生成和消亡造成分配和GC压力。在设计时可以简单的做如下推导:
首先考虑只有单线程的情况,此时简单的构建一个 Queue 容器,对象回收时放入 Queue ,分配时从 Queue 取出,如果 Queue 中已经没有对象实例了,则创建一个新的实例。这种方式非常容易就构建了一个单线程的对象池实现。额外需要考虑的细节就是为 Queue 设置一个大小的上限,避免池化的对象实例过多而导致消耗太多的内存。
接着考虑多线程的情况,分配时与单线程情况相同