18.JVM变量槽Slot

 

1.JVM变量槽Slot的理解

1.Slot是局部变量表中最基本的存储单元。
2.参数值的存放总是从局部变量表数组的index 0开始,到数组的-1的索引结束。
3.局部变量表中存放的是局部变量,包括8种基本数据类型,引用数据类型,returnAddress类型的变量。
4.32位以内的数据占用一个Slot(包括returnAddress类型,引用数据类型),64位类型的(long, double)占用两个Slot
在这里插入图片描述
5.JVM会为局部变量表中的每一个Slot分配一个访问索引,通过这个索引来访问局部变量。
6.当一个实例方法(非静态方法)被调用的时候,它的方法参数和方法体内部定义的局部变量将会按照顺序被复制到局部变量的每一个Slot上。
7.如果需要访问局部变量表中的一个64位的局部变量值时,只需要使用前一个索引即可。(例如:访问longdouble类型的变量)
8.如果当前栈帧是由构造方法或者实例方法创建的,那么该对象引用this将会存放在index0slot处,其余的参数按照参数表的顺序继续进行存储。
在这里插入图片描述
理解Slot的例子演示:

package jvn;

import java.util.Date;

public class LocalVariablesTest {
    private int count = 0;

    public static void main(String[] args) {
        LocalVariablesTest test = new LocalVariablesTest();
        int num = 10;
        test.test1();
    }

    //练习:
    public static void testStatic(){
        LocalVariablesTest test = new LocalVariablesTest();
        Date date = new Date();
        int count = 10;
        System.out.println(count);
        //因为this变量不存在于当前方法的局部变量表中!!
//        System.out.println(this.count);
    }

    //关于Slot的使用的理解
    public LocalVariablesTest(){
        this.count = 1;
    }

    public void test1() {
        Date date = new Date();
        String name1 = "atguigu.com";
        test2(date, name1);
        System.out.println(date + name1);
    }

    public String test2(Date dateP, String name2) {
        dateP = null;
        name2 = "songhongkang";
        double weight = 130.5;//占据两个slot
        char gender = '';
        return dateP + name2;
    }

    public void test3() {
        this.count++;
    }
}

编译上面的java代码,使用Jclasslib打开生成的LocalVariablesTest.class文件。关于JClasslib的使用参考:https://blog.csdn.net/u011069294/article/details/107079185
1.选中test1方法:
Name列可以看到总共存储了3个局部变量,this,date,以及name1。验证了上面讲到的,当一个方法是构造方法或者实例方法的时候,对象引用this会被存储到局部变量表的index=0的位置,然后其他的局部变量按顺序存储。
Index列可以看出,每个变量的索引的起始位置以及所占的slot数目。this索引起始位置是0,它下一个变量data索引起始位置是1,说明this占了一个Solt。同理可以看出data也占了一个Slot
在这里插入图片描述
2.选中test2方法:
同样可以看出第一个变量存储的是this。后面的变量按顺序存储。
特别需要注意的一点的是变量weight是一个Double数据类型,索引起始位置是3,结束位置是5,所以它占了两个Slot
在这里插入图片描述
3.选中<init>方法
可以看到构造方法只存储了一个this
在这里插入图片描述
9.Slot是可以重复利用的。如果一个局部变量出了其作用域,那么在其作用域之后声明的新的局部变量就很可能会重复使用过期的局部变量的槽位。
在这里插入图片描述
SLot重复利用的例子:

package jvn;

public class LocalVariablesTest {
    
    public void test4() {
        int a = 0;
        {
            int b = 0;
            b = a + 1;
        }
        //变量c使用之前已经销毁的变量b占据的slot的位置
        int c = a + 1;
    }
}

同样使用Jclasslib打开LocalVariablesTest.class
1.选中test4方法。
可以看出,变量c和变量b的索引起始地址都是2,所以变量c复用了变量bSlot
在这里插入图片描述

posted @ 2020-11-18 10:35  跃小云  阅读(446)  评论(0编辑  收藏  举报