Netty之轻量级对象池Recycler

为什么说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代码  收藏代码

  1. public abstract class Recycler<T> {  
  2.     private final ThreadLocal<Stack<T>> threadLocal = new ThreadLocal<Stack<T>>() {  
  3.         @Override  
  4.         protected Stack<T> initialValue() {  
  5.             return new Stack<T>(Recycler.this, Thread.currentThread());  
  6.         }  
  7.     };  
  8.     public final T get() {  
  9.         Stack<T> stack = threadLocal.get();  
  10.         T o = stack.pop();  
  11.         if (o == null) {  
  12.             o = newObject(stack);  
  13.         }  
  14.         return o;  
  15.     }  
  16.     public final boolean recycle(T o, Handle handle) {  
  17.         @SuppressWarnings("unchecked")  
  18.         Stack<T> stack = (Stack<T>) handle;  
  19.         if (stack.parent != this) {  
  20.             return false;  
  21.         }  
  22.         if (Thread.currentThread() != stack.thread) {  
  23.             return false;  
  24.         }  
  25.         stack.push(o);  
  26.         return true;  
  27.     }  
  28.     protected abstract T newObject(Handle handle);  
  29.     public interface Handle { }  
  30.     static final class Stack<T> implements Handle {  
  31.         private static final int INITIAL_CAPACITY = 256;  
  32.         final Recycler<T> parent;  
  33.         final Thread thread;  
  34.         private T[] elements;  
  35.         private int size;  
  36.         private final Map<T, Boolean> map = new IdentityHashMap<T, Boolean>(INITIAL_CAPACITY);  
  37.         @SuppressWarnings({ "unchecked", "SuspiciousArrayCast" })  
  38.         Stack(Recycler<T> parent, Thread thread) {  
  39.             this.parent = parent;  
  40.             this.thread = thread;  
  41.             elements = newArray(INITIAL_CAPACITY);  
  42.         }  
  43.         T pop() {  
  44.             int size = this.size;  
  45.             if (size == 0) {  
  46.                 return null;  
  47.             }  
  48.             size --;  
  49.             T ret = elements[size];  
  50.             elements[size] = null;  
  51.             map.remove(ret);  
  52.             this.size = size;  
  53.             return ret;  
  54.         }  
  55.   
  56.         void push(T o) {  
  57.             if (map.put(o, Boolean.TRUE) != null) {  
  58.                 throw new IllegalStateException("recycled already");  
  59.             }  
  60.   
  61.             int size = this.size;  
  62.             if (size == elements.length) {  
  63.                 T[] newElements = newArray(size << 1);  
  64.                 System.arraycopy(elements, 0, newElements, 0, size);  
  65.                 elements = newElements;  
  66.             }  
  67.   
  68.             elements[size] = o;  
  69.             this.size = size + 1;  
  70.         }  
  71.   
  72.         @SuppressWarnings({ "unchecked", "SuspiciousArrayCast" })  
  73.         private static <T> T[] newArray(int length) {  
  74.             return (T[]) new Object[length];  
  75.         }  
  76.     }  
  77. 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));  
    }  
}  

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值