netty源码阅读之性能优化工具类之Recycle同线程回收对象

38 篇文章 1 订阅
33 篇文章 1 订阅

我们从handle的recycle方法开始:

        @Override
        public void recycle(Object object) {
            if (object != value) {
                throw new IllegalArgumentException("object does not belong to handle");
            }
            stack.push(this);
        }

然后进入stack.push:

        void push(DefaultHandle<?> item) {
            Thread currentThread = Thread.currentThread();
            if (thread == 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, we need to signal that the push
                // happens later.
                pushLater(item, currentThread);
            }
        }

非常简单,thread是我们创建stack的时候保存的thread参数,当前线程和创建stack的线程是同一个线程就调用pushNow(item),我们现在是分析同线程,后面一篇文章再分析异线程,所以进入pushNow:

        private void pushNow(DefaultHandle<?> item) {
            if ((item.recycleId | item.lastRecycledId) != 0) {
                throw new IllegalStateException("recycled already");
            }
            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;
            }
            if (size == elements.length) {
                elements = Arrays.copyOf(elements, min(size << 1, maxCapacity));
            }

            elements[size] = item;
            this.size = size + 1;
        }

首先看

            if ((item.recycleId | item.lastRecycledId) != 0) {
                throw new IllegalStateException("recycled already");
            }

如果是第一次回收,recycleId和lastRecycleId都是0,否则只要有一个不为0,那么就说明回收过,就抛出已经回收过的异常。

然后正常的流程就是需要把recycleId和lastRecycleId赋值:

            item.recycleId = item.lastRecycledId = OWN_THREAD_ID;

看这个OWN_THREAD_ID:

 private static final int OWN_THREAD_ID = ID_GENERATOR.getAndIncrement();

也就是在一个Recycler类里面,这个OWN_THREAD_ID是唯一固定的。

返回。

有两种情况需要不回收然后return的:

            if (size >= maxCapacity || dropHandle(item)) {
                // Hit the maximum capacity or should drop - drop the possibly youngest object.
                return;
            }

size>=maxCapacity的时候,也就是大小已经超过最大大小了,放不下了。

第二种情况,dropHandle返回true的时候,也就是:

        boolean dropHandle(DefaultHandle<?> handle) {
            if (!handle.hasBeenRecycled) {
                if ((++handleRecycleCount & ratioMask) != 0) {
                    // Drop the object.
                    return true;
                }
                handle.hasBeenRecycled = true;
            }
            return false;
        }

handleRecycleCount就是目前回收对象的个数,ratioMask就是7(0X00000111),也就是说,每隔8个对象判断一次,表示只回收八分之一的对象。

最后看:

            if (size == elements.length) {
                elements = Arrays.copyOf(elements, min(size << 1, maxCapacity));
            }

elements一开始不一定就分配maxCapacity的容量,如果容量满了,那就size<<1左移两位也就是两倍,然后和maxCapacity之间取一个最小的来扩容,把扩容的值又给elements,最后通过:

            elements[size] = item;
            this.size = size + 1;

将回收的对象放到elements里面。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值