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

网友投稿 670 2022-10-15

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

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

前文传送门: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) NOOP_HANDLE);

}

Stack stack = threadLocal.get();

DefaultHandle 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_HANDLQsYOujrLE是一个handle, 我们看其定义:

private static final Handle NOOP_HANDLE = new Handle() {

@Override

public void recycle(Object object) {

}

};

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

回到get方法中

我们看第二步

Stack stack = threadLocal.get();

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

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

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

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

我们跟进newHandle方法

DefaultHandle newHandle() {

return new DefaultHandle(this);

}

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

跟到DefaultHandle的构造方法中:

DefaultHandle(Stack> stack) {

this.stack = stack;

}

这里初始化了stack属性

DefaultHandle中还有个value的成员变量

private Object value;

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

回到get方法中:

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

DefaultHandle handle = stack.pop();

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

跟到pop方法中

DefaultHandle 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) NOOP_HANDLE);

}

Stack stack = threadLocal.get();

DefaultHandle handle = stack.pop();

if (handle == null) {

handle = stack.newHandle();

handle.value = newObject(handle);

}

return (T) handle.value;

}

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

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:LeetCode刷题之旅(中等-1): 3. 无重复字符的最长子串
下一篇:LeetCode刷题之旅【多线程篇】简单 - 1:按序打印
相关文章

 发表评论

暂时没有评论,来抢沙发吧~