PooledByteBuf分配及回收之十四Recycler.Stack<T> 弹出对象

PooledByteBufAllocator初始化

PoolThreadCache初始化

PoolAerna初始化

PoolChunk初始化

PoolSubpage初始化

PooledUnsafeDirectByteBuf初始化

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

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

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

PoolChunkList源码解析

ReferenceCountUpdater源码解析

Recycler及基内部类初始化

Recycler.Stack<T> 压入对象

Recycler.Stack<T> 弹出对象

PooledByteBuf的回收

弹出对象

        DefaultHandle<T> pop() {

            int size = this.size;
            //先判断size是否==0
            if (size == 0) {
                //从WeakOrderQueue中扫出对象放入elements数组中
                if (!scavenge()) {
                    return null;
                }
                size = this.size;
                if (size <= 0) {
                    // double check, avoid races
                    return null;
                }
            }
            //size减1
            size --;
            DefaultHandle ret = elements[size];
            elements[size] = null;
            // 因为我们已经将element [size]设置为null,所以在进行任何验证之前,我们还需要存储更新的大小。否则,当以后尝试再次弹出而之前未添加新元素时,我们可能会看到null值。
            this.size = size;
           
            if (ret.lastRecycledId != ret.recycleId) {
                throw new IllegalStateException("recycled multiple times");
            }
            ret.recycleId = 0;
            ret.lastRecycledId = 0;
            return ret;
        }

 

 scavenge()

        private boolean scavenge() {
            // continue an existing scavenge, if any
            if (scavengeSome()) {
                return true;
            }

            // reset our scavenge cursor
            prev = null;
            cursor = head;
            return false;
        }

        private boolean scavengeSome() {

            WeakOrderQueue prev;

            WeakOrderQueue cursor = this.cursor;
            //如果游标为空,设置游标=head
            if (cursor == null) {
                prev = null;
                cursor = head;
                //如果游标还是空,那么池中没有对象,返回false
                if (cursor == null) {
                    return false;
                }
            } else {
                prev = this.prev;
            }

            boolean success = false;
            do {
                //WeakOrderQueue中的对象转换到elements数组中
                if (cursor.transfer(this)) {
                    success = true;
                    break;
                }
                WeakOrderQueue next = cursor.getNext();
                if (cursor.get() == null) {
                    // If the thread associated with the queue is gone, unlink it, after
                    // performing a volatile read to confirm there is no data left to collect.
                    // We never unlink the first queue, as we don't want to synchronize on updating the head.
                    if (cursor.hasFinalData()) {
                        for (;;) {
                            if (cursor.transfer(this)) {
                                success = true;
                            } else {
                                break;
                            }
                        }
                    }

                    if (prev != null) {
                        // Ensure we reclaim all space before dropping the WeakOrderQueue to be GC'ed.
                        cursor.reclaimAllSpaceAndUnlink();
                        prev.setNext(next);
                    }
                } else {
                    prev = cursor;
                }

                cursor = next;

            } while (cursor != null && !success);

            this.prev = prev;
            this.cursor = cursor;
            return success;
        }

 

WeakOrderQueue.transfer(stack)

        boolean transfer(Stack<?> dst) {
            //拿到第一个Link
            Link head = this.head.link;
            //为空则说明WorkQueue中无对象
            if (head == null) {
                return false;
            }
            //判断Link中对象是否已被读取
            if (head.readIndex == LINK_CAPACITY) {
                //已被读取,则取下一个Link,下一个Link为空则说明WorkQueue中无对象
                if (head.next == null) {
                    return false;
                }
                head = head.next;
                //设置Head连接到新的Link,其中有一个隐藏的释放上一个Link对象数量操作
                this.head.relink(head);
            }

            //Link中可用对象的起点下标
            final int srcStart = head.readIndex;
            //Link中可用对象的终点下标
            int srcEnd = head.get();
            //Link中可用对象的数量
            final int srcSize = srcEnd - srcStart;

            if (srcSize == 0) {
                return false;
            }
            
            //stack中对象的数量
            final int dstSize = dst.size;
            //期望对象的数量
            final int expectedCapacity = dstSize + srcSize;
            //如果期望对象的数量大于stack.elements的长度,则stack.elements扩容
            if (expectedCapacity > dst.elements.length) {
                final int actualCapacity = dst.increaseCapacity(expectedCapacity);
                srcEnd = min(srcStart + actualCapacity - dstSize, srcEnd);
            }

            if (srcStart != srcEnd) {
                final DefaultHandle[] srcElems = head.elements;
                final DefaultHandle[] dstElems = dst.elements;
                int newDstSize = dstSize;
                for (int i = srcStart; i < srcEnd; i++) {
                    DefaultHandle<?> element = srcElems[i];
                    //设置对象的recycleId=lastRecycledId
                    if (element.recycleId == 0) {
                        element.recycleId = element.lastRecycledId;
                    } else if (element.recycleId != element.lastRecycledId) {
                        throw new IllegalStateException("recycled already");
                    }
                    
                    srcElems[i] = null;
                    //尝试丢弃这个对象
                    if (dst.dropHandle(element)) {
                        // Drop the object.
                        continue;
                    }
                    element.stack = dst;
                    //将对象加入到stack的数组中
                    dstElems[newDstSize ++] = element;
                }
                
                if (srcEnd == LINK_CAPACITY && head.next != null) {
                    //设置Head连接到新的Link,其中有一个隐藏的释放上一个Link对象数量操作
                    this.head.relink(head.next);
                }
                //设置head的readIndex
                head.readIndex = srcEnd;
                
                if (dst.size == newDstSize) {
                    return false;
                }

                dst.size = newDstSize;

                return true;
            } else {
                // The destination stack is full already.
                return false;
            }
        }

            
            void relink(Link link) {
                reclaimSpace(LINK_CAPACITY);
                this.link = link;
            }

            private void reclaimSpace(int space) {
                availableSharedCapacity.addAndGet(space);
            }

        //stack.elements扩容
        int increaseCapacity(int expectedCapacity) {
            int newCapacity = elements.length;
            int maxCapacity = this.maxCapacity;
            do {
                newCapacity <<= 1;
            } while (newCapacity < expectedCapacity && newCapacity < maxCapacity);

            newCapacity = min(newCapacity, maxCapacity);
            if (newCapacity != elements.length) {
                elements = Arrays.copyOf(elements, newCapacity);
            }

            return newCapacity;
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值