文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

前文传送门: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获取对象的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯