我们上几篇文章分析了池化内存的使用:PoolChunk和PoolSubPage
我们通过代码看到了池化内存后将一些信息都记录到了ByteBuf的实现类上。在allocat()方法之前都会调用newByteBuf()返回一个实例,那个在这个过程干了什么呢,我们需要也了解下。
整个Recycler进行对象缓存使用,减少对象多次创建和GC回收性能消耗。
1.PooledDirectByteBuf.newInstance(maxCapacity)
我们还是以PooledDirectByteBuf为例:
static PooledDirectByteBuf newInstance(int maxCapacity) {
PooledDirectByteBuf buf = RECYCLER.get();
buf.reuse(maxCapacity);
return buf;
}
这个实现有点似曾相识的感觉,在PooledByteBufAllocator中newHeapBuffer()也有类似的处理:
PoolThreadCache cache = threadCache.get();
那么看下这个RECYCLER的实现处理:
final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private static final Recycler<PooledDirectByteBuf> RECYCLER = new Recycler<PooledDirectByteBuf>() {
@Override
protected PooledDirectByteBuf newObject(Handle<PooledDirectByteBuf> handle) {
return new PooledDirectByteBuf(handle, 0);
}
};
}
一个简单的Recycler子类,我们稍后留意下这个**newObject()**方法是怎么用的,我们转到get()方法中:
public final T get() {
if (maxCapacityPerThread == 0) {
return newObject((Handle<T>) NOOP_HANDLE);
}
Stack<T> stack = threadLocal.get();
DefaultHandle<T> handle = stack.pop();
if (handle == null) {
handle = stack.newHandle();
handle.value = newObject(handle);
}
return (T) handle.value;
}
我们看到了熟悉的threadLocal,可以看到Recycler中的threadLocal中存储的属性是:Stack。
- Recycler中的threadLocal
private final FastThreadLocal<Stack<T>> threadLocal = new FastThreadLocal<Stack<T>>() {
@Override
protected Stack<T> initialValue