netty源码阅读之性能优化工具类之Recycler的创建

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

我们进入到Recycler的构造函数:

    protected Recycler() {
        this(DEFAULT_MAX_CAPACITY_PER_THREAD);
    }

然后在这个类里面,有一个threadLocal,里面放了一个stack:

    private final FastThreadLocal<Stack<T>> threadLocal = new FastThreadLocal<Stack<T>>() {
        @Override
        protected Stack<T> initialValue() {
            return new Stack<T>(Recycler.this, Thread.currentThread(), maxCapacityPerThread, maxSharedCapacityFactor,
                    ratioMask, maxDelayedQueuesPerThread);
        }
    };

这个stack就是放我们的handle的。

看看stack的成员变量:

        // we keep a queue of per-thread queues, which is appended to once only, each time a new thread other
        // than the stack owner recycles: when we run out of items in our stack we iterate this collection
        // to scavenge those that can be reused. this permits us to incur minimal thread synchronisation whilst
        // still recycling all items.
        final Recycler<T> parent;
        final Thread thread;
        final AtomicInteger availableSharedCapacity;
        final int maxDelayedQueues;

        private final int maxCapacity;
        private final int ratioMask;
        private DefaultHandle<?>[] elements;
        private int size;
        private int handleRecycleCount = -1; // Start with -1 so the first one will be recycled.
        private WeakOrderQueue cursor, prev;
        private volatile WeakOrderQueue head;

parent:不用说就是当前的Recycler

thread:当前的thread

maxDelayedQueues:我们的对象可能在一个线程里面创建(get),另外一个线程那里释放,这个对象就不会放在第一个线程的数组里,而是放在另外一个线程的WeakOrderQueue里面。那么一个线程创建的对象可以在多少个不同的线程里面缓存呢?就是这个值了

找默认值:

        MAX_DELAYED_QUEUES_PER_THREAD = max(0,
                SystemPropertyUtil.getInt("io.netty.recycler.maxDelayedQueuesPerThread",
                        // We use the same value as default EventLoop number
                        Runtime.getRuntime().availableProcessors() * 2));

 也就是我们处理器的个数的两倍。

maxCapacity:这个stack的最大容量,也就是池的大小,也就是一个线程里面最多可以放多少个对象。

找来找去我们可以看到他的默认值是:

    private static final int DEFAULT_INITIAL_MAX_CAPACITY_PER_THREAD = 32768; // Use 32k instances as default.

也就是我们一个数组里面可以放32k个对象。

availableSharedCapacity:上面讲了可以在不同的线程释放缓存对象,这个参数就是一个线程里面可以缓存别的线程对象的最大的个数。

默认值是:

            availableSharedCapacity = new AtomicInteger(max(maxCapacity / maxSharedCapacityFactor, LINK_CAPACITY));

而这个maxSharedCapacityFactor的默认值可以找到:


        MAX_SHARED_CAPACITY_FACTOR = max(2,
                SystemPropertyUtil.getInt("io.netty.recycler.maxSharedCapacityFactor",
                        2));

是2。 

LINK_CAPACITY默认值是16:

        LINK_CAPACITY = safeFindNextPositivePowerOfTwo(
                max(SystemPropertyUtil.getInt("io.netty.recycler.linkCapacity", 16), 16));

结合前面我们要分析的maxCapacity默认值为32k,我们可以知道这个availableSharedCapacity是32k/2=16k。 

也就是说线程里面可以拥有自己的对象是32k个,外部线程的对象是16k个。

 

ratioMask:每次通过调用recycle把对象进行回收的时候,它并不是每次都会把对象进行回收的,这个参数用来控制对象回收的频率。

先看这个RATIO的默认值:

/ By default we allow one push to a Recycler for each 8th try on handles that were never recycled before.
        // This should help to slowly increase the capacity of the recycler while not be too sensitive to allocation
        // bursts.
        RATIO = safeFindNextPositivePowerOfTwo(SystemPropertyUtil.getInt("io.netty.recycler.ratio", 8));

然后:

    protected Recycler(int maxCapacityPerThread, int maxSharedCapacityFactor,
                       int ratio, int maxDelayedQueuesPerThread) {
        ratioMask = safeFindNextPositivePowerOfTwo(ratio) - 1;
        if (maxCapacityPerThread <= 0) {
            this.maxCapacityPerThread = 0;
            this.maxSharedCapacityFactor = 1;
            this.maxDelayedQueuesPerThread = 0;
        } else {
            this.maxCapacityPerThread = maxCapacityPerThread;
            this.maxSharedCapacityFactor = max(1, maxSharedCapacityFactor);
            this.maxDelayedQueuesPerThread = max(0, maxDelayedQueuesPerThread);
        }
    }

 所以这个是7

elements:这个就是这个stack里面的元素了,都是DefaultHandler

cursor、prev、head:这个就是存放了其他线程的链表的指针,也就是WeakOrderQueue的指针,后续我们好好分析。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值