JVM详解之:汇编角度理解本地变量的生命周期
简介
java方法中定义的变量,它的生命周期是什么样的呢?是不是一定要等到方法结束,这个创建的对象才会被回收呢?
带着这个问题我们来看一下今天的这篇文章。
本地变量的生命周期
在类中,变量类型有类变量,成员变量和本地变量。
本地变量指的是定义在方法中的变量,如果我们在方法中定义了一个变量,那么这个变量的生命周期是怎么样的呢?
举个例子:
public void test(){
Object object = new Object();
doSomeThingElse(){
...
}
}
在上面的test方法中,定义了一个object本地变量,然后又执行了一个方法。
因为在java中,我们无法直接控制对象的生命周期,对象的回收是由垃圾回收器自动进行的。
通常来说这个object对象会维持到整个test执行结束才会被回收。
现在我们考虑一个特殊的情况,如果doSomeThingElse这个方法是一个while循环,并且永远不会结束,那么这个创建出来的object对象会不会被回收呢?还是一直都存在内存中?
先说我们的结论,JVM非常智能,可以检测出来这种情况,将object对象进行回收。
举例说明
为了能够更好的说明问题,我们自定义一个Test对象,并在其创建和被回收之前打印相应的信息。
public static class Test {
public Test() {
System.out.println("创建对象 " + this);
}
public void test() {
System.out.println("测试对象 " + this);
}
@Override
protected void finalize() throws Throwable {
System.out.println("回收对象 " + this);
}
}
然后做两个测试,第一个测试没有无限循环,第二个测试保持无限循环,循环通过一个volatile变量flag来控制:
public static void main(String[] args) throws InterruptedException {
System.out.println("开始测试1");
resetFlag();
flag = true;
testLocalVariable();
System.out.println("等待Test1结束");
Thread.sleep(10000);
System.out.println("开始测试2");
flag = true;
testLocalVariable();
}
看一下testLocalVariable方法的定义:
public static void testLocalVariable() {
Test test1 = new Test();
Test test2 = new Test();
while (flag) {
// 啥都不做
}
test1.test();
}
然后我们再启动一个线程做定时的GC。好了一切就绪,我们运行吧:
开始测试1
创建对象 com.flydean.LocalVariableReachability$Test@119d7047
创建对象 com.flydean.LocalVariableReachability$Test@776ec8df
回收对象 com.flydean.LocalVariableReachability$Test@776ec8df
测试对象 com.flydean.LocalVariableReachability$Test@119d7047
等待Test1结束
回收对象 com.flydean.LocalVariableReachability$Test@119d7047
开始测试2
创建对象 com.flydean.LocalVariableReachability$Test@4eec7777
创建对象 com.flydean.LocalVariableReachability$Test@3b07d329
回收对象 com.flydean.LocalVariableReachability$Test@3b07d329
先看测试1的结果,我们可以看到第二个对象在调用test1.test()之前就被回收了。
再看测试2的结果,我们可以看到第二个对象同样被回收了。
结果说明了JVM是足够智能的,可以自行优化本地变量的生命周期。
优化的原因
我们考虑一下,JVM是在什么阶段对本地变量的生命周期进行优化的呢?
很明显,这个优化不是在编译期间进行的,而是在运行期中进行的优化。
我们使用-XX:+PrintAssembly分析一下汇编代码:

首先说明,本人的汇编语言还是很多年前学过的,如果解释起来有错误的地方,请多多指正。
先说两个概念rbx和r10都是64位CPU的寄存器,r10d是r10的低32位。
先看红框1, 红框1表示rbx中保存的是我们定义的LocalVariableReachability类中的一个Test对象。
再看红框2,红框2表示r10现在保存的是LocalVariableReachability这个类实例。
红框3表示的是进入while循环的时候,ImutableOopMap中存储的对象,大家可以看到里面只有r10和rbx,也就是说只有类实例和其中的一个Test实例。
红框4是什么呢?红框4表示的是一个safe point,也就是垃圾回收的时候的安全点。在这个安全点上如果有不再被使用的对象就会被回收。
因为ImutableOopMap中只存有两个对象,那么剩下的一个Test实例就会被回收。
总结
本文介绍了本地变量的生命周期,并在汇编语言的角度对其进行了解释,如有错误欢迎指正。
本文作者:flydean程序那些事
本文链接:http://www.flydean.com/jvm-local-variable-reachability/
本文来源:flydean的博客
欢迎关注我的公众号:程序那些事,更多精彩等着您!
JVM详解之:汇编角度理解本地变量的生命周期的更多相关文章
- ARP协议详解之ARP动态与静态条目的生命周期
ARP协议详解之ARP动态与静态条目的生命周期 ARP动态条目的生命周期 动态条目随时间推移自动添加和删除. q 每个动态ARP缓存条目默认的生命周期是两分钟.当超过两分钟,该条目会被删掉.所以,生 ...
- JVM详解总结
JVM详解总结 1.JVM内存模型 1.1 运行时数据区内存分布实例 1.2 类加载的生命周期 2.物理内存与虚拟内存 3.Java中需要使用内存的组件 3.1 Java堆 3.2 线程 3.3 类和 ...
- Mysql加锁过程详解(8)-理解innodb的锁(record,gap,Next-Key lock)
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- JNI详解---从不懂到理解
转载:https://blog.csdn.net/hui12581/article/details/44832651 Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 C ...
- JVM 详解
概念 数据类型 Java 虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对 ...
- jdk与jre与jdk都是干什么的有什么区别和jvm详解:
1.0,jdk与jre和jvm的区别: JDK(Java Development Kit):指的是Java开发工具集.JDK是整个Java的核心,包括了Java基础类库.Java运行环境(JRE)和J ...
- WmS详解(二)之如何理解Window和窗口的关系?基于Android7.0源码
上篇博客(WmS详解(一)之token到底是什么?基于Android7.0源码)中我们简要介绍了token的作用,这里涉及到的概念非常多,其中出现频率最高的要数Window和窗口这一对搭档了,那么我们 ...
- 百度大脑UNIT3.0详解之嵌入式对话理解技术
相信很多人都体验过手机没有网时的焦虑,没有网什么也做不了.而机器人也会遇到这样的时刻,没有网或者网络环境不好的情况下,无法识别用户在说什么,也无法回复用户.在AIoT(AI+物联网)飞速普及的现在,智 ...
- OPCode详解及汇编与反汇编原理
1. 何为OPCode 在计算机科学领域中,操作码(Operation Code, OPCode)被用于描述机器语言指令中,指定要执行某种操作的那部分机器码,构成OPCode的指令格式和规范由处理器的 ...
随机推荐
- 前端工程化的的理解,浅谈web工程化的开发流程
1. 什么是前端工程化 自有前端工程师这个称谓以来,前端的发展可谓是日新月异.相比较已经非常成熟的其他领域,前端虽是后起之秀,但其野蛮生长是其他领域不能比的.虽然前端技术飞快发展,但是前端整体的工程生 ...
- css盒子模型的深入理解,在块级、行内元素的区别和特性
css盒子模型用于处理元素的内容.内边距.边框和外边距的方式简称.元素框的最内部分是实际的内容,直接包围内容的是内边距.内边距呈现了元素的背景.内边距的边缘是边框.边框以外是外边距,外边距默认是透明的 ...
- 《 ZooKeeper : Wait-free coordination for Internet-scale systems 》论文研读
Zookeeper 研读 说明:本文为论文 < ZooKeeper : Wait-free coordination for Internet-scale systems > 的个人理解, ...
- 微服务框架Demo.MicroServer运行手册
一.背景说明: 之前分享过一个微服务开发框架, "享一个集成.NET Core+Swagger+Consul+Polly+Ocelot+IdentityServer4+Exceptionle ...
- day63 django入门(4)
目录 一.CBV源码解析 二.模版语法 1 传值 2 过滤器(最多只能传两个参数) 3 标签 4 自定义过滤器,标签,inclusion_tag 4.1 自定义过滤器 4.2 自定义标签(可以传多个参 ...
- day06 可变不可变类型
1.可变不可变类型 可变类型 定义:值改变,id不变,改的是原值 不可变类型 定义:值改变,id也变了,证明是产生了新的值没有改变原值 验证 x = 10 print(id(x)) x = 11 pr ...
- 本地缓存解决方案-Caffeine Cache
1.1 关于Caffeine Cache Google Guava Cache是一种非常优秀本地缓存解决方案,提供了基于容量,时间和引用的缓存回收方式.基于容量的方式内部实现采用LRU算法,基于引 ...
- Django 【基础篇】
前戏 python Web程序 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env python #cod ...
- 在linux下修改文件夹机器子文件夹的权限
使用命令:chmod 用法:chmod [选项]... 模式[,模式]... 文件... 或:chmod [选项]... 八进制模式 文件... 或:chmod [选项]... --reference ...
- Python Ethical Hacking - BACKDOORS(1)
REVERSE_BACKDOOR Access file system. Execute system commands. Download files. Upload files. Persiste ...