Netty源码分析第八章: 高性能工具类FastThreadLocal和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);
}
这个通过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源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第4节: recycler中获取对象的更多相关文章
-
Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->;第1节: FastThreadLocal的使用和创建
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 概述: FastThreadLocal我们在剖析堆外内存分配的时候简单介绍过, 它类似于JDK的ThreadL ...
-
Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->;第7节: 获取异线程释放的对象
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第七节: 获取异线程释放的对象 上一小节分析了异线程回收对象, 原理是通过与stack关联的WeakOrder ...
-
Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->;第2节: FastThreadLocal的set方法
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第二节: FastThreadLocal的set方法 上一小节我们学习了FastThreadLocal的创建和 ...
-
Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->;第3节: recycler的使用和创建
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第三节: recycler的使用和创建 这一小节开始学习recycler相关的知识, recycler是n ...
-
Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->;第5节: 同线程回收对象
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第五节: 同线程回收对象 上一小节剖析了从recycler中获取一个对象, 这一小节分析在创建和回收是同线程的 ...
-
Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->;第6节: 异线程回收对象
Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第六节: 异线程回收对象 异线程回收对象, 就是创建对象和回收对象不在同一条线程的情况下, 对象回收的逻辑 我 ...
-
Netty源码分析第3章(客户端接入流程)---->;第1节: 初始化NioSockectChannelConfig
Netty源码分析第三章: 客户端接入流程 概述: 之前的章节学习了server启动以及eventLoop相关的逻辑, eventLoop轮询到客户端接入事件之后是如何处理的?这一章我们循序渐进, 带 ...
-
Netty源码分析第3章(客户端接入流程)---->;第2节: 处理接入事件之handle的创建
Netty源码分析第三章: 客户端接入流程 第二节: 处理接入事件之handle的创建 上一小节我们剖析完成了与channel绑定的ChannelConfig初始化相关的流程, 这一小节继续剖析客户端 ...
-
Netty源码分析第3章(客户端接入流程)---->;第3节: NioSocketChannel的创建
Netty源码分析第三章: 客户端接入流程 第三节: NioSocketChannel的创建 回到上一小节的read()方法: public void read() { //必须是NioEventLo ...
随机推荐
-
新版Xcode无法新建iOS空项目解决方案
--感谢同学分享-- 操作说明: 拷贝Empty Application.xctemplate文件夹至 /Contents/Developer/Platforms/iPhoneOS.platfor ...
-
GitHub简单教程
Hello World程序是计算机编程中由来已久的惯例,这是一个当你在学习新事物的时候开始的一个简单的小练习.让我们开始GitHub的"Hello World". 你将学会: - ...
-
一个等待页面加载完毕的loading动画
1 html 部分 <!DOCTYPE html><html><head><meta http-equiv="Content-Type" ...
-
语义化的html结构的好处
HTML是提供网页文档内容的上下文结构和含义:html本身是没有表现的,我们看到例如<h1>是粗体,字体大小2em,加粗:<strong>是加粗的,不要认为这是html的表现, ...
-
Javascript进阶篇——(DOM—节点---属性、访问节点)—笔记整理
节点属性在文档对象模型 (DOM) 中,每个节点都是一个对象.DOM 节点有三个重要的属性 : 1. nodeName : 节点的名称 2. nodeValue :节点的值 3. nodeType : ...
-
一个php创建webservice,并通过c#调用的真实实例
最近需要用php创建webservice供C#和JAVA来调用,通过3天的搜索和尝试,终于成功在C#下调用,JAVA的调用还没开始,为防止忘记,在这里记录下来全过程. 本文参考了许多文章,文中也采用了 ...
-
(解决tomcat端口被占用的问题)create[8005]java.net.BindException: Address already in use: JVM_Bind
create[8005]java.net.BindException: Address already in use: JVM_Bind”,原来是Tomcat8005端口被其他进程占用,8005端口是 ...
-
Python web框架总结
web框架总结 前提 一个web框架需要包含的组件或者功能有: router orm request and response cookies and session template engine ...
-
Microsoft Windows Server 2012 Ad域搭建
Microsoft Windows Server 2012 Ad域搭建 一.Active Directory概念 AD(活动目录):是一种组织资源信息的方法,目录的意义在于我们可以通过标题或者说搜索条 ...
-
monkey_recorder录制monkeyrunner脚本
转载:monkey_recorder录制monkeyrunner脚本 1. 你必须有android sdk, sdk的tools文件家里有一个monkeyrunner.bat.2. 将如下内容拷贝 ...