简介

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详解之:汇编角度理解本地变量的生命周期的更多相关文章

  1. ARP协议详解之ARP动态与静态条目的生命周期

    ARP协议详解之ARP动态与静态条目的生命周期 ARP动态条目的生命周期 动态条目随时间推移自动添加和删除. q  每个动态ARP缓存条目默认的生命周期是两分钟.当超过两分钟,该条目会被删掉.所以,生 ...

  2. JVM详解总结

    JVM详解总结 1.JVM内存模型 1.1 运行时数据区内存分布实例 1.2 类加载的生命周期 2.物理内存与虚拟内存 3.Java中需要使用内存的组件 3.1 Java堆 3.2 线程 3.3 类和 ...

  3. Mysql加锁过程详解(8)-理解innodb的锁(record,gap,Next-Key lock)

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  4. JNI详解---从不懂到理解

    转载:https://blog.csdn.net/hui12581/article/details/44832651 Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 C ...

  5. JVM 详解

    概念 数据类型 Java 虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对 ...

  6. jdk与jre与jdk都是干什么的有什么区别和jvm详解:

    1.0,jdk与jre和jvm的区别: JDK(Java Development Kit):指的是Java开发工具集.JDK是整个Java的核心,包括了Java基础类库.Java运行环境(JRE)和J ...

  7. WmS详解(二)之如何理解Window和窗口的关系?基于Android7.0源码

    上篇博客(WmS详解(一)之token到底是什么?基于Android7.0源码)中我们简要介绍了token的作用,这里涉及到的概念非常多,其中出现频率最高的要数Window和窗口这一对搭档了,那么我们 ...

  8. 百度大脑UNIT3.0详解之嵌入式对话理解技术

    相信很多人都体验过手机没有网时的焦虑,没有网什么也做不了.而机器人也会遇到这样的时刻,没有网或者网络环境不好的情况下,无法识别用户在说什么,也无法回复用户.在AIoT(AI+物联网)飞速普及的现在,智 ...

  9. OPCode详解及汇编与反汇编原理

    1. 何为OPCode 在计算机科学领域中,操作码(Operation Code, OPCode)被用于描述机器语言指令中,指定要执行某种操作的那部分机器码,构成OPCode的指令格式和规范由处理器的 ...

随机推荐

  1. pandas | 使用pandas进行数据处理——Series篇

    本文始发于个人公众号:TechFlow,原创不易,求个关注 上周我们关于Python中科学计算库Numpy的介绍就结束了,今天我们开始介绍一个新的常用的计算工具库,它就是大名鼎鼎的Pandas. Pa ...

  2. nginx location 知识知多少

    写在之前 众所周知 nginx location 路由转发规则多种多样,尤其是 [ = | ~ | ~* | ^~ ] 这些前缀是什么意思.root 与 alias 是否可以区分开,nginx 作为反 ...

  3. 数据解析_xpath

    重点推荐这种解析方式,xpath是最常用且最便捷高效的一种解析方式,通用性 1.解析原理 1.实例化一个etree的对象,且需要将被解析的页面源码数据加载到改对象中. 2.调用etree对象中的xpa ...

  4. Java_面试札记

    Java_面试札记  为了不死,我愿献出生命 背景:记录下寄几和friend在2020年Java面试中遇到的problem. 1.MySQL索引结构? 基本上所有的索引都是B-Tree结构,还有一部分 ...

  5. 转载---最简单的JavaScript模板引擎

    转载自:http://www.cnblogs.com/dolphinX/p/3489269.html,http://blog.jobbole.com/56689/

  6. python爬京东(带GUI)

    最近写了个专门爬百度的,后来又想爬京东的,还是采用上次的BeautifulSoup+requests模块 下面直接上代码,看不懂的可以看这篇文章或者注释来学习 #!/usr/bin/env pytho ...

  7. day39 作业

    实现生产消费原理 from multiprocessing import Process,JoinableQueue import time import random def cooker(q): ...

  8. java 面向对象(二十七):注解的使用

    1. 注解的理解① jdk 5.0 新增的功能*② Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理.通过使用 Annotation, ...

  9. 05 flask源码剖析之配置加载

    05 Flask源码之:配置加载 目录 05 Flask源码之:配置加载 1.加载配置文件 2.app.config源码分析 3.from_object源码分析 4. 总结 1.加载配置文件 from ...

  10. How to change the text color in the terminal

    You can open the file ~/.bashrc and then choose the force_color_prompt=yes otherwise, you can change ...