文章目录

  • 简介
  • 本地变量的生命周期
  • 举例说明
  • 优化的原因
  • 总结

简介

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);}@Overrideprotected 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. Delphi匿名方法(三):扩展本地变量的生命周期

    本地变量,一般是随着函数执行结束,就不能再访问: 而如果在匿名函数,访问了外部函数的本地变量,本地变量的生命周期会被扩展 unit Unit1;interfaceusesWinapi.Windows, ...

  3. Java虚拟机(Jvm详解)

    Java虚拟机(Jvm详解) 总体知识点框架 1.运行时数据区域 线程私有的: 程序计数器 虚拟机栈 本地方法栈 线程共享的: 堆 方法区 直接内存 (非运行时数据区的一部分) Java 虚拟机规范对 ...

  4. java vm 远程监控配置文件_Java VisualVM监控远程JVM(详解)

    我们经常需要对我们的开发的软件做各种测试, 软件对系统资源的使用情况更是不可少, 目前有多个监控工具, 相比JProfiler对系统资源尤其是内存的消耗是非常庞大,JDK1.6开始自带的VisualV ...

  5. JVM详解——什么是JVM、JVM优点

    JVM详解--什么是JVM.JVM优点 最近在学习Java,经常在书中看到JVM这三个字母,那到底什么是JVM呢? 并且JVM的知识在Java面试中也是非常受面试官青睐的知识点,那对于JVM我们到底要 ...

  6. 视频教程-C语言-从汇编角度理解C语言的本质-C/C++

    C语言-从汇编角度理解C语言的本质 擅长JavaWeb开发,游戏逆向外挂与反外挂,游戏保护对抗 孙冉 ¥49.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅 ...

  7. smali语言详解之字段的声明(变量、常量)

    smali语言详解之字段的声明(变量.常量) 一.smali语言的字段声明格式 1.1.非静态变量 .field 权限修饰关键字 变量名:变量类型的全包名路径或与java对应的数据类型关键字 1.2. ...

  8. Storm精华问答 | 如何理解spout/bolt的生命周期?

    戳蓝字"CSDN云计算"关注我们哦! Storm是Twitter开源的分布式实时大数据处理框架,被业界称为实时版Hadoop.随着越来越多的场景对Hadoop的MapReduce高 ...

  9. 深入理解 Android Activity的生命周期

    深入理解 Android Activity的生命周期 2010-10-13 14:08:29|  分类: Android |  标签:周期  调用  activity  android  protec ...

最新文章

  1. 解决vim没有颜色的办法
  2. php正则表达式2,php正则表达式(2)
  3. 程序员要避免的五种程序注释方式
  4. excel 两组数据交点_初识Python 数据可视化
  5. TCP三次握手和四次挥手过程
  6. Linux入门学习(二)
  7. 乐华娱乐前训练生黄智博卖口罩诈骗案宣判:获刑三年三个月
  8. 网页粒子背景插件 -Canvas-nest.js
  9. 各种UNIX系统下root密码的修复
  10. php视图最佳实践,PHP 的最佳实践
  11. sql_全国省市区、邮编、经纬度、城市拼音、电话区号
  12. java基于springboot+vue校园电动自行车管理系统
  13. graphpad prism横坐标怎么设置不显示数值_graphpad,prism,符号显示有问题
  14. 论文中常用的对word页眉页脚的操作
  15. Overleaf使用Latex输入中文的两种方法
  16. Altium Designer PCB电路板设计总结
  17. 大成182672 浅谈网络推广
  18. Qt界面总是显示在前方
  19. 计量经济学之时间序列分析学习笔记(单位根检验、协整检验、单整阶数判断、ECM建模)——基于R(二)
  20. Vue 发布文件压缩

热门文章

  1. java大话_大话JAVA(一)
  2. HDU4577(2013年ACM杭州赛区邀请赛B题)
  3. python3之协程(1)---协程简介
  4. FFmpeg基本组成
  5. 【玩转cocos2d-x之三十二】xml的解析
  6. cocos2d-x游戏实例(20)-纵版射击游戏(7)
  7. WSAAccept()函数使用解析
  8. C 的CList,CPtrList,CObList,CStringList 用法之CPtrList
  9. 读《Android 安全架构深究》
  10. 干货:如何正确描述存储IO类型?