www.px111.net:JVM详解之:汇编角度明白内陆变量的生命周期

admin 2个月前 (08-30) 科技 24 0

目录
  • 简介
  • 内陆变量的生命周期
  • 举例说明
  • 优化的缘故原由
  • 总结

简介

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的博客

迎接关注我的民众号:程序那些事,更多精彩等着您!

,

联博开奖网

www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。

皇冠体育声明:该文看法仅代表作者自己,与本平台无关。转载请注明:www.px111.net:JVM详解之:汇编角度明白内陆变量的生命周期

网友评论

  • (*)

最新评论

标签列表

    文章归档

    站点信息

    • 文章总数:640
    • 页面总数:0
    • 分类总数:8
    • 标签总数:960
    • 评论总数:272
    • 浏览总数:9380