Netty对象池Recycler---ByteBuf的创建与回收---结构介绍

PoolArena#allocate:分配内存的入口

    PooledByteBuf<T> allocate(PoolThreadCache cache, int reqCapacity, int maxCapacity) {
        PooledByteBuf<T> buf = newByteBuf(maxCapacity);
        allocate(cache, buf, reqCapacity);
        return buf;
    }

我们看到了buf的创建由newByteBuf,这个buf对象用来承载分配的内存。我们看一下直接内存的分配,堆内内存类似。

        protected PooledByteBuf<ByteBuffer> newByteBuf(int maxCapacity) {
            if (HAS_UNSAFE) {
                return PooledUnsafeDirectByteBuf.newInstance(maxCapacity);
            } else {
                return PooledDirectByteBuf.newInstance(maxCapacity);
            }
        }

PooledUnsafeDirectByteBuf#newInstance:一个静态方法创建了一个buf对象,用来承载分配的内存。

    static PooledUnsafeDirectByteBuf newInstance(int maxCapacity) {
        PooledUnsafeDirectByteBuf buf = RECYCLER.get();
        buf.reuse(maxCapacity);
        return buf;
    }

对象是由对象池RECYCLER获取的。RECYCLER是一个staic final变量。

    private static final Recycler<PooledUnsafeDirectByteBuf> RECYCLER = new Recycler<PooledUnsafeDirectByteBuf>() {
        @Override
        protected PooledUnsafeDirectByteBuf newObject(Handle<PooledUnsafeDirectByteBuf> handle) {
            return new PooledUnsafeDirectByteBuf(handle, 0);
        }
    };

首先看Recycler的构造:主要是对一些容量的设置以及一个FastTreadLocal类型的Stack。还有一个一个FastTreadLocal类型的weakHashMap

public abstract class Recycler<T> {
    private static final InternalLogger logger = InternalLoggerFactory.getInstance(Recycler.class);
    private static final Recycler.Handle NOOP_HANDLE = new Recycler.Handle() {
        public void recycle(Object object) {
        }
    };
    private static final AtomicInteger ID_GENERATOR = new AtomicInteger(-2147483648);
    private static final int OWN_THREAD_ID;
    private static final int DEFAULT_INITIAL_MAX_CAPACITY_PER_THREAD = 32768;
    private static final int DEFAULT_MAX_CAPACITY_PER_THREAD;
    private static final int INITIAL_CAPACITY;
    private static final int MAX_SHARED_CAPACITY_FACTOR;
    private static final int MAX_DELAYED_QUEUES_PER_THREAD;
    private static final int LINK_CAPACITY;
    private static final int RATIO;
    private final int maxCapacityPerThread;
    private final int maxSharedCapacityFactor;
    private final int ratioMask;
    private final int maxDelayedQueuesPerThread;
    // 一个ftl的栈
    private final FastThreadLocal<Recycler.Stack<T>> threadLocal;
    // 一个ftl的weakHashMap
    private static final FastThreadLocal<Map<Recycler.Stack<?>, Recycler.WeakOrderQueue>> DELAYED_RECYCLED;
...
...

我们看一下Stack:

    static final class Stack<T> {
        // 保存外部类的引用
        final Recycler<T> parent;
        // 保存自己属于的线程
        final Thread thread;
        final AtomicInteger availableSharedCapacity;
        final int maxDelayedQueues;
        private final int maxCapacity;
        private final int ratioMask;
        // 装载对象的数组
        private Recycler.DefaultHandle<?>[] elements;
        private int size;
        private int handleRecycleCount = -1;
        // 三个指针
        private Recycler.WeakOrderQueue cursor;
        private Recycler.WeakOrderQueue prev;
        // volatile修饰了
        private volatile Recycler.WeakOrderQueue head;

...
...
...

大致结构:head指针主要是连接各个WeakOrderQueue,而prev和cursor是变量整条head链表的å¨è¿éæå¥å¾çæè¿°

我们在看一下这个map :是一个WeakHashMap。键是stack的weak引用。Value是WeakOrderQueue

    private static final FastThreadLocal<Map<Stack<?>, WeakOrderQueue>> DELAYED_RECYCLED =
            new FastThreadLocal<Map<Stack<?>, WeakOrderQueue>>() {
        @Override
        protected Map<Stack<?>, WeakOrderQueue> initialValue() {
            return new WeakHashMap<Stack<?>, WeakOrderQueue>();
        }
    };

多线程创建和回收对象(A线程创建对象,B线程回收这个对象),为了不出现多线程同时去存取操作Stack而产生的竞争情况,就区分了当前线程是不是Stack的拥有线程,如果是,就直接放回到Stack中,如果不是,就放入对应的WeakOrderQueue中,前面说了Stack和WeakOrderQueue有对应关系。而且多个线程中都可能有同一个Stack的不同WeakOrderQueue。他们之间是用单链表连起来的。大致关系就像这样:head指针就是stack里面的å¨è¿éæå¥å¾çæè¿°

 我们看一下WeakOrderQueue:在构建的时候加入到stack中的head链表中,使用的是头插法,用synchronized 修饰,保证head链表修改的线程安全。

        private WeakOrderQueue(Stack<?> stack, Thread thread) {
            head = tail = new Link();
            owner = new WeakReference<Thread>(thread);
            synchronized (stack) {
                next = stack.head;
                stack.head = this;
            }

            // Its important that we not store the Stack itself in the WeakOrderQueue as the Stack also is used in
            // the WeakHashMap as key. So just store the enclosed AtomicInteger which should allow to have the
            // Stack itself GCed.
            availableSharedCapacity = stack.availableSharedCapacity;
        }

看一下结构å¨è¿éæå¥å¾çæè¿°

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值