Netty分布式高性能工具类同线程下回收对象解析

网友投稿 294 2022-08-17


Netty分布式高性能工具类同线程下回收对象解析

目录同线程回收对象回顾第三小节的demo中的main方法我们跟进recycle方法然后获取当前size

同线程回收对象

上一小节剖析了从recycler中获取一个对象, 这一小节分析在创建和回收是同线程的前提下, 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);

}

这里就是一个同线程回收对象的典型场景, 在一个线程中将对象创建并且回收, 我们的User对象定义了recycle方法

static class User{

private final Recycler.Handle handle;

public User(Recycler.Handle handle){

this.handle=handle;

}

public void recycle(){

handle.recycle(this);

}

}

这里的recycle是通过handle对象的recycle方法实现对象回收的, 这里实际调用的是DefaultHandle的recycle方法

我们跟进recycle方法

public void recycle(Object object) {

if (object != value) {

throw new IllegalArgumentException("object does not belong to handle");

}

stack.push(this);

}

这里如果回收的对象为null, 则抛出异常

如果不为null, 则通过自身绑定stack的push方法将自身push到stack中

跟到push方法中:

void push(DefaultHandle> item) {

Thread currentThread = Thread.currentThread();

if (thread == currentThread) {

pushNow(item);

} else {

pushLater(item, currentThread);

}

}

这里首先判断当前线程, 和创建stack的时候保存的线程是否是同一线程, 如果是, 说明是同线程回收对象, 则执行pushNow方法将对象放入stack中

跟到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)) {

return;

}

if (size == elements.length) {

elements = Arrays.copyOf(elements, min(size << 1, maxCapacity));

}

elements[size] = item;

this.size = size + 1;

}

如果第一次回收, item.recycleId和item.lastRecycledId都为0, 所以不会进入if块, 我们继续往下看

item.recycleId = item.lastRecycledId = OWN_THREAD_ID 这一步将handle的recycleId和lastRecycledId赋值为OWN_THREAD_ID, OWN_THREAD_ID在每一个recycle中是唯一固定的, 这里我们只需要记得这个概念就行

然后获取当前size

如果size超过上限大小, 则直接返回

这里还有个判断dropHandle, 我们跟进去:

boolean dropHandle(DefaultHandle> handle) {

if (!handle.hasBeenRecycled) {

if ((++handleRecycleCount & ratioMask) != 0) {

return true;

}

handle.hasBeenRecycled = true;

}

return false;

}

if (!handle.hasBeenRecycled) 表示当前对象之前是否没有被回收过, 如果是第一次回收, 这里会返回true, 然后进入放到if

再看if中的判断

if ((++handleRecycleCount & ratioMask) != 0)

handleRecycleCount表示当前位置stack回收了多少次对象(回收了多少次, 不代表回收了多少个对象, 因为不是每次回收都会被成功的保存在stack), ratioMask我们之前分析过是7, 这里 (++handleRecycleCouddvEXnt & ratioMask) != 0 表示回收的对象数如果不是8的倍数, 则返回true, 表示只回收1/8的对象

然后将hasBeenRecycled设置为true, 表示已经被回收

回到pushNow方法中:

如果size的大小等于stack中的数组elements的大小, 则将数组elements进行扩容

最后将size通过数组下标的方式将当前handle设置到elements的元素中, 并将size进行自增

以上就是同线程回收对象的逻辑,更多关于Netty分布式同线程回收对象的资料请关注我们其它相关文章!


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

上一篇:MyBatis实现注册及获取Mapper
下一篇:Netty分布式从recycler对象回收站获取对象过程剖析
相关文章

 发表评论

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