Netty分布式从recycler对象回收站获取对象过程剖析

2022-07-16,,,,

前文传送门:netty分布式高性能工具类recycler的使用及创建

对象回收站获取对象

我们回顾上一小节demo的main方法中

从回收站获取对象

public static void main(string[] args){
    user user1 = recycler.get();
    user1.recycle();
    user user2 = recycler.get();
    user2.recycle();
    system.out.println(user1==user2);
}

这个通过recycler的get方法获取对象, 我们跟到get方法中:

public final t get() {
    if (maxcapacityperthread == 0) {
        return newobject((handle<t>) noop_handle);
    }
    stack<t> stack = threadlocal.get();
    defaulthandle<t> handle = stack.pop();
    if (handle == null) {
        handle = stack.newhandle();
        handle.value = newobject(handle);
    }
    return (t) handle.value;
}

首先判断maxcapacityperthread是否为0, maxcapacityperthread代表stack最多能缓存多少个对象, 如果缓存0个, 说明对象将一个都不会回收

这个通过调用newobject创建一个对象, 并传入一个noop_handle, noop_handle是一个handle, 我们看其定义:

private static final handle noop_handle = new handle() {
    @override
    public void recycle(object object) {
        
    }
};

这里的recycle方法是一个空实现, 代表不进行任何对象回收

回到get方法中

我们看第二步 

stack<t> stack = threadlocal.get(); 

这里通过fastthreadlocal对象拿到当前线程的stack, 有关fastthreadlocal获取对象的逻辑之前小节剖析过, 这里不再赘述

获取stack之后, 从stack中pop出一个handle, 这个handle做用我们稍后分析

如果取出的对象为null, 说明当前回收站内没有任何对象, 通常第一次执行到这里对象还没回收, 这里就会是null, 这样则会通过stack.newhandle()创建一个handle

创建出来的handle的value属性, 通过我们重写的newobject方法进行赋值, 也就是我们demo中的user

我们跟进newhandle方法

defaulthandle<t> newhandle() {
    return new defaulthandle<t>(this);
}

这里创建一个defaulthandle对象, 并传入this, 这里的this是当前stack

跟到defaulthandle的构造方法中:

defaulthandle(stack<?> stack) {
    this.stack = stack;
}

这里初始化了stack属性

defaulthandle中还有个value的成员变量

private object value;

这里的value就用来绑定回收的对象本身

回到get方法中:

分析handle, 我们回到上一步:

defaulthandle<t> handle = stack.pop();

我们分析从stack中弹出一个handle的逻辑

跟到pop方法中

defaulthandle<t> pop() {
    int size = this.size;
    if (size == 0) {
        if (!scavenge()) {
            return null;
        }
        size = this.size;
    }
    size --;
    defaulthandle ret = elements[size];
    elements[size] = null;
    if (ret.lastrecycledid != ret.recycleid) {
        throw new illegalstateexception("recycled multiple times");
    }
    ret.recycleid = 0;
    ret.lastrecycledid = 0;
    this.size = size;
    return ret;
}

首先拿到size, size表示当前stack的对象数

如果size为0, 则调用scavenge方法, 这个方法是异线程回收对象的方法, 我们放在之后的小节进行分析

size大于零, 则size进行自减, 代表取出一个元素

然后通过size的数组下标的方式将handle取出

之后将当前下标设置为null

最后将属性recycleid, lastrecycledid, size进行赋值

recycleid和lastrecycledid我们会在之后的小节进行分析

回到get方法中:

public final t get() {
    if (maxcapacityperthread == 0) {
        return newobject((handle<t>) noop_handle);
    }
    stack<t> stack = threadlocal.get();
    defaulthandle<t> handle = stack.pop();
    if (handle == null) {
        handle = stack.newhandle();
        handle.value = newobject(handle);
    }
    return (t) handle.value;
}

无论是从stack中弹出的handle, 还是创建的handle, 最后都要通过handle.value拿到我们实际使用的对象

以上就是从对象回收站获取对象的过程,更多关于netty分布式recycler获取对象的资料请关注其它相关文章!

《Netty分布式从recycler对象回收站获取对象过程剖析.doc》

下载本文的Word格式文档,以方便收藏与打印。