为什么说Recycler是“轻量级”的对象池?
功能简单:对象池只提供了创建和回收的基本接口,没有复杂的诸如有效性检测、空闲回收和拒绝策略等一些复杂功能。
逻辑简单:实现逻辑清晰简单,没有复杂的算法逻辑。
Recycler核心方法
- get(): 获取一个对象;
- recycle(T, Handle): 回收一个对象,T为对象泛型;
- newObject(Handle): 当没有可用对象时创建对象的实现方法;
Recycler核心类
- DefaultHandle: 对象的包装类,在Recycler中缓存的对象都会包装成DefaultHandle类。
- Stack: 存储本线程回收的对象 。对象的获取和回收对应Stack的pop和push,即获取对象时从Stack中pop出1个DefaultHandle,回收对象时将对象包装成DefaultHandle push到Stack中。Stack会与线程绑定,即每个用到Recycler的线程都会拥有1个Stack,在该线程中获取对象都是在该线程的Stack中pop出一个可用对象。
- WeakOrderQueue: 存储其它线程回收到本线程stack的对象 ,当某个线程从Stack中获取不到对象时会从WeakOrderQueue中获取对象。每个线程的Stack拥有1个WeakOrderQueue链表,链表每个节点对应1个其它线程的WeakOrderQueue,其它线程回收到该Stack的对象就存储在这个WeakOrderQueue里。
- Link: WeakOrderQueue中包含1个Link链表,回收对象存储在链表某个Link节点里,当Link节点存储的回收对象满了时会新建1个Link放在Link链表尾。
Recycler创建和回收流程
netty使用基于thread-local的轻量级对象池Recycler对ChannelOutboundBuffer进行回收。当ChannelOutboundBuffer第一次被实例化且使用完毕后,会回收到Recycler中(见下面的recyle方法),下次需要用时,直接从Recycler中取(见下面的get方法),避免了再次实例化和垃圾回收的开销。
Java代码
- public abstract class Recycler<T> {
- private final ThreadLocal<Stack<T>> threadLocal = new ThreadLocal<Stack<T>>() {
- @Override
- protected Stack<T> initialValue() {
- return new Stack<T>(Recycler.this, Thread.currentThread());
- }
- };
- public final T get() {
- Stack<T> stack = threadLocal.get();
- T o = stack.pop();
- if (o == null) {
- o = newObject(stack);
- }
- return o;
- }
- public final boolean recycle(T o, Handle handle) {
- @SuppressWarnings("unchecked")
- Stack<T> stack = (Stack<T>) handle;
- if (stack.parent != this) {
- return false;
- }
- if (Thread.currentThread() != stack.thread) {
- return false;
- }
- stack.push(o);
- return true;
- }
- protected abstract T newObject(Handle handle);
- public interface Handle { }
- static final class Stack<T> implements Handle {
- private static final int INITIAL_CAPACITY = 256;
- final Recycler<T> parent;
- final Thread thread;
- private T[] elements;
- private int size;
- private final Map<T, Boolean> map = new IdentityHashMap<T, Boolean>(INITIAL_CAPACITY);
- @SuppressWarnings({ "unchecked", "SuspiciousArrayCast" })
- Stack(Recycler<T> parent, Thread thread) {
- this.parent = parent;
- this.thread = thread;
- elements = newArray(INITIAL_CAPACITY);
- }
- T pop() {
- int size = this.size;
- if (size == 0) {
- return null;
- }
- size --;
- T ret = elements[size];
- elements[size] = null;
- map.remove(ret);
- this.size = size;
- return ret;
- }
- void push(T o) {
- if (map.put(o, Boolean.TRUE) != null) {
- throw new IllegalStateException("recycled already");
- }
- int size = this.size;
- if (size == elements.length) {
- T[] newElements = newArray(size << 1);
- System.arraycopy(elements, 0, newElements, 0, size);
- elements = newElements;
- }
- elements[size] = o;
- this.size = size + 1;
- }
- @SuppressWarnings({ "unchecked", "SuspiciousArrayCast" })
- private static <T> T[] newArray(int length) {
- return (T[]) new Object[length];
- }
- }
-
PooledDirectByteBuf 是缓存的DirectByteBuf. 用RECYCLER来做回收重复利用。调用memory的get方法获取数据。memory是一个DirectByteBuffer对象。
final class PooledDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private static final Recycler<PooledDirectByteBuf> RECYCLER = new Recycler<PooledDirectByteBuf>() {
@Override
protected PooledDirectByteBuf newObject(Handle handle) {
return new PooledDirectByteBuf(handle, 0);
}
};
static PooledDirectByteBuf newInstance(int maxCapacity) {
PooledDirectByteBuf buf = RECYCLER.get();
buf.setRefCnt(1);
buf.maxCapacity(maxCapacity);
return buf;
}
@Override
protected byte _getByte(int index) {
return memory.get(idx(index));
}
@Override
protected short _getShort(int index) {
return memory.getShort(idx(index));
}
}