Netty对象池-RECYCLER原理
- 1.RECYCLER专门分配和回收netty的bytebuf对象的
- 2.其有newObject方法需要实现,而该方法需要的参数是一个Handle接口,该接口有个默认方法要实现
也就是recycle。所以一般的Recycler对象new的时候如下
private static final Recycler<PooledUnsafeDirectByteBuf> RECYCLER = new Recycler<PooledUnsafeDirectByteBuf>() {
@Override
protected PooledUnsafeDirectByteBuf newObject(Handle<PooledUnsafeDirectByteBuf> handle) {
return new PooledUnsafeDirectByteBuf(handle, 0);
}
};
上述代表我们的RECYCLER主要是生成PooledUnsafeDirectByteBuf对象,而且 我们这个对象内部需要将handle与PooledUnsafeDirectByteBuf绑定,
这样对象回收的时候就使用handle的recycle方法。
- 3.当我们调用其get方法的时候逻辑是如下方式:
- 4.首先查看是否已经到达每个线程能承担的最大容量(maxCapacityPerThread),如果是则直接获取一个新的我们需要的对象,且传递了一个recycle实现是空的handle这样就算代表这个对象不会去回收。
- 5.当没超过maxCapacityPerThread则从threadlocal中获取一个stack,该stack内部存储一个DefaultHandle,该DefaultHandle帮我们默认实现了recycle,他会把对象(defaulthandle本身)存放进入stack。即每个DefaultHandle内部持有一个stack,而每个线程都为一个threadlocal存储一个固定的stack。
- 6.我们回收的时候recyclerHandle的recycle然后把我们的recyclerHandle放入栈中,放入栈之前需要比较value是否与PooledUnsafeDirectByteBuf一致。
- 7.其实整个recycle原理如下:每个loop线程有一个stack(底层是数组实现),stack里面存储的是DefaultHandle,DefaultHandle内部持有我们的bytebuf。当我们想获取一个bytebuf 我就优先从stack里面获取,如果没有在尝试从WeakOrderQueue获取,如果WeakOrderQueue还没有则new一个出来。
- 8.那么WeakOrderQueue是什么,首先我们的bytebuf对象被回收一般如果是被自己线程执行回收会直接放入stack中,如果是其他线程尼?为了避免锁竞争。通过threadlocal给其他线程建立一个map,key就是stack本身而value则是WeakOrderQueue,WeakOrderQueue里面存放的是lin数组,每一个数组都是一个defaulthandle的数组。而且属于某个stack的WeakOrderQueue会被串联成一个链表。
网友评论