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

作者:向南是个万人迷 时间:2021-08-12 06:45:48 

前文传送门: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拿到我们实际使用的对象

来源:https://www.cnblogs.com/xiangnan6122/p/10208952.html

标签:Netty,分布式,recycler,获取对象,对象回收
0
投稿

猜你喜欢

  • 说说@ModelAttribute在父类和子类中的执行顺序

    2022-07-31 17:59:55
  • Mybatis使用@Select注解sql中使用in问题

    2023-01-06 20:52:48
  • spring-boot-maven-plugin 配置有啥用

    2022-08-27 19:09:25
  • C#中的一些延时函数

    2023-11-29 04:33:30
  • 详解Spring Boot Oauth2缓存UserDetails到Ehcache

    2023-02-26 21:57:12
  • springboot实现注册加密与登录解密功能(demo)

    2021-12-15 15:10:08
  • spring mvc4中相关注解的详细讲解教程

    2021-10-11 23:21:17
  • Entity Framework映射TPH、TPT、TPC与继承类

    2022-10-18 04:52:52
  • C#读写xml文件方法总结(超详细!)

    2023-11-23 13:16:40
  • Java垃圾回收器的方法和原理总结

    2022-06-27 07:11:46
  • 详解Springboot分布式限流实践

    2021-07-12 14:29:18
  • 不使用Math.random方法生成随机数(随机数生成器)

    2021-11-28 05:08:46
  • Spring中SmartLifecycle和Lifecycle的作用和区别

    2023-11-18 22:55:50
  • Java开发完整短信验证码功能的全过程

    2023-05-05 15:35:24
  • Java中如何动态创建接口的实现方法

    2023-11-25 15:13:02
  • Android实现一个丝滑的自动轮播控件实例代码

    2022-01-24 03:08:19
  • Springboot内置的工具类之CollectionUtils示例讲解

    2023-08-23 20:47:13
  • 详解C# 中的正则表达式运用

    2023-04-20 06:35:03
  • Filter、Servlet、Listener的学习_动力节点Java学院整理

    2021-08-12 00:05:49
  • 浅谈java的接口和C++虚类的相同和不同之处

    2023-08-05 12:01:51
  • asp之家 软件编程 m.aspxhome.com