PooledByteBuf分配及回收之十三Recycler.Stack<T> 压入对象

PooledByteBufAllocator初始化

PoolThreadCache初始化

PoolAerna初始化

PoolChunk初始化

PoolSubpage初始化

PooledUnsafeDirectByteBuf初始化

分配微小型PooledByteBuf(未命中缓存场景)

分配小型PooledByteBuf(未命中缓存场景)

分配普通型PooledByteBuf(未命中缓存场景)

PoolChunkList源码解析

ReferenceCountUpdater源码解析

Recycler及基内部类初始化

Recycler.Stack<T> 压入对象

Recycler.Stack<T> 弹出对象

PooledByteBuf的回收

压入对象

        void push(DefaultHandle<?> item) {
            Thread currentThread = Thread.currentThread();
            if (threadRef.get() == currentThread) {
                // The current Thread is the thread that belongs to the Stack, we can try to push the object now.
                pushNow(item);
            } else {
                // The current Thread is not the one that belongs to the Stack
                // (or the Thread that belonged to the Stack was collected already), we need to signal that the push
                // happens later.
                pushLater(item, currentThread);
            }
        }

pushNow

        private void pushNow(DefaultHandle<?> item) {
            //item未回收前recycleId=lastRecycledId=0
            if ((item.recycleId | item.lastRecycledId) != 0) {
                throw new IllegalStateException("recycled already");
            }
            //设置item的recycleId,lastRecycledId 等于 Recycler的OWN_THREAD_ID
            item.recycleId = item.lastRecycledId = OWN_THREAD_ID;

            int size = this.size;
            //如果对象数>=最大容量或者成功丢弃对象则直接返回
            if (size >= maxCapacity || dropHandle(item)) {
                // Hit the maximum capacity or should drop - drop the possibly youngest object.
                return;
            }
            //扩容成原elements.length的2倍
            if (size == elements.length) {
                elements = Arrays.copyOf(elements, min(size << 1, maxCapacity));
            }
            //设置对象
            elements[size] = item;
            //对象数+1
            this.size = size + 1;
        }

        //丢弃对象
        boolean dropHandle(DefaultHandle<?> handle) {
            //判断对象未被回收过
            if (!handle.hasBeenRecycled) {
                // handleRecycleCount的初始值等于interval 所以第一个对象不会被丢弃
                // interval=8 也就是每回收一个对象,之后的8个对象就会被丢弃
                if (handleRecycleCount < interval) {
                    handleRecycleCount++;
                    // Drop the object.
                    return true;
                }
                
                handleRecycleCount = 0;
                //设置对象为被回收
                handle.hasBeenRecycled = true;
            }
            return false;
        }

pushLater

        private void pushLater(DefaultHandle<?> item, Thread thread) {
            if (maxDelayedQueues == 0) {
                // 我们不支持跨线程回收,而是将其直接丢弃。
                return;
            }

            // we don't want to have a ref to the queue as the value in our weak map
            // so we null it out; to ensure there are no races with restoring it later
            // we impose a memory ordering here (no-op on x86)
            Map<Stack<?>, WeakOrderQueue> delayedRecycled = DELAYED_RECYCLED.get();
            WeakOrderQueue queue = delayedRecycled.get(this);
            if (queue == null) {
                if (delayedRecycled.size() >= maxDelayedQueues) {
                    // 添加一个虚拟队列,以便我们知道应该删除对象
                    delayedRecycled.put(this, WeakOrderQueue.DUMMY);
                    return;
                }
                // 检查是否已经达到延迟队列的最大数量,是否可以分配。
                if ((queue = newWeakOrderQueue(thread)) == null) {
                    // drop object
                    return;
                }
                delayedRecycled.put(this, queue);
            } else if (queue == WeakOrderQueue.DUMMY) {
                // drop object
                return;
            }

            queue.add(item);
        }


    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>();
        }
    };

        private WeakOrderQueue newWeakOrderQueue(Thread thread) {
            return WeakOrderQueue.newQueue(this, thread);
        }

        static WeakOrderQueue newQueue(Stack<?> stack, Thread thread) {
            
            if (!Head.reserveSpaceForLink(stack.availableSharedCapacity)) {
                return null;
            }
            final WeakOrderQueue queue = new WeakOrderQueue(stack, thread);
            //注意这里,设置了stack的head
            stack.setHead(queue);

            return queue;
        }

 WorkOrderQueue.add

        void add(DefaultHandle<?> handle) {
            //设置lastRecycledId
            handle.lastRecycledId = id;

            //如果handleRecycleCount < interval则丢弃对象
            if (handleRecycleCount < interval) {

                handleRecycleCount++;
                
                return;
            }

            handleRecycleCount = 0;

            Link tail = this.tail;

            int writeIndex;

            // writeIndex==LINK_CAPACITY(16)时需要创建一个link
            if ((writeIndex = tail.get()) == LINK_CAPACITY) {

                Link link = head.newLink();

                if (link == null) {
                    // 如果不能创建link 则丢弃对象
                    return;
                }

                // 相当于  this.tail = link,tail = link,tail.next = link
                this.tail = tail = tail.next = link;
                //重新给writeIndex赋值
                writeIndex = tail.get();
            }
            //将对象添加到数组中的writeIndex位置
            tail.elements[writeIndex] = handle;
            //去除handle对stack的引用
            handle.stack = null;
            //我们延迟设置以确保将设置堆栈设置为null,然后再在拥有线程中将其取消为空; 这也意味着如果我们看到索引已更新,我们就保证队列中元素的可见性
            // lazySet 不保证tail的值对其它线程的可见性
            tail.lazySet(writeIndex + 1);
        }

Heak.newLink()

            Link newLink() {
                return reserveSpaceForLink(availableSharedCapacity) ? new Link() : null;
            }
            
            //每个link的元素数量为LINK_CAPACITY(16),stack中所有link的元素数量不能超过availableSharedCapacity
            static boolean reserveSpaceForLink(AtomicInteger availableSharedCapacity) {
                for (;;) {
                    int available = availableSharedCapacity.get();
                    //如果可用的元素数量小于LINK_CAPACITY,则代表不能再创建link
                    if (available < LINK_CAPACITY) {
                        return false;
                    }
                    //预先扣除新link占用的元素数量LINK_CAPACITY
                    if (availableSharedCapacity.compareAndSet(available, available - LINK_CAPACITY)) {
                        return true;
                    }
                }
            }

 

Stack的数据结构

DefaultHandle<?>[] elements  数组,初始长度为256,最大长度为4*1024

WeakOrderQueue head  指向Stack对应的WeakOrderQueue

WeakOrderQueue的数据结构

WeakOrderQueue  由一系列(2*1024/16个)Link组成,每个Link持有一个长度为16的DefaultHandle<?>[] elements  数组

注意点

Stack与WeakOrderQueue的handleRecycleCount与interval

  • 初始值 handleRecycleCount=interval=8
  • 第一个压入的对象直接进入数组,然后handleRecycleCount变为0
  • 后续压入的对象会丢弃,handleRecycleCount加1
  • handleRecycleCount==8的时候  压入的对象直接进入数组,然后handleRecycleCount变为0

Stack 的size 只在pushNow的时候才会增加

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值