我的JVM学习笔记:运行时数据区(2)局部变量表详解

感谢尚硅谷宋红康老师的JVM入门到精通课程,向每一个用心做免费教课程的老师致敬!
本套教程均为我学习课程之后的学习笔记,防止遗忘,并发送给大家分享,感谢大家查看~

1.虚拟机栈详解

本章衔接上篇文章:我的JVM学习笔记:第三章——运行时数据区(1),有需要的请点击查看。

栈贞的内部结构

栈贞内部包含:

  • 局部变量表(Local variables)
  • 操作数栈(operand Stack) ( 或表达式栈)
  • 动态链接(Dynamic Linking) ( 或指向运行时常量池的方法引用)
  • 方法返回地址(Return Address) (或方法正常退 出或者异常退出的定义)
  • 一些附加信息
    在这里插入图片描述
    注意:栈帧包含方法的所有信息,栈帧也是有大小的,栈帧越小,可同时执行的方法就越多

局部表量表

也叫作:局部变量表、局部变量数组。

那么为什么叫局部变量数组呢?

因为:局部变量表定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类基本数据类型、对象引用(reference) ,以及returnAddress(返回值)。

注意:由于局部变量表是建立在线程的栈上,是线程的私有数据,因此不存在数据安全问题。

并且:局部变量表所需的容量大小是在编译期确定下来的,并保存在方法的Code属性的maximun local variables数据项中。在方法运行期间是不会改变局部变量表的大小的。

测试:

public static void main(String[] args) {
    String a = "aaaa";
    int b = 1;
    float c = 1.1f;
    boolean d = true;
    Object f = new Object();
}

测试命令:

javap -v 

结果:
在编译完成后局部变量表即确定,包含方法中所有变量(包括方法参数)。
在这里插入图片描述

注意:
局部变量表中的变量只在当前方法调用中有效。在方法执行时,虚拟机通过使用局部变量表完成参数值到参数变量列表的传递过程。当方法调用结束后,随着方法栈帧的销毁,局部变量表也会随之销毁

并且:由于局部变量表内一般存储信息较多,所以局部变量表是决定栈帧大小的主要因素之一!

变量槽(Slot)

局部变量表最基本的存储单元就是变量槽。

参数值的存放总是在局部变量数组的index0开始,到数组长度-1的索引结束。
在局部变量表里,32位以内的类型只占用一个slot (包括returnAddress类型),64位的类型(long和double)占用两个slot
注意:sort,byte,boolean等数据也占用一个变量槽,因为jvm会在存储时将上述变量转为int类型(变量槽是最基本存储单元,无法分割,只能整个使用)。

也就是说:局部量量表实际上就是一个变量槽数组,每个变量槽可存储32位数据,不足32位的数组自动转换为32位填充,64位数据会占用两个变量槽,局部变量表中会记录数据存储在变量槽的索引位置。

在这里插入图片描述
JVM会为局部变量表中每一个变量分配变量槽,并记录其的存储位置,比如变量args就存储在index为0的变量槽中,变量c因为为64位,需要占用两个变量槽(3和4),变量D因为C占用了两个变量槽,所以直接从index5处开始存储。
在这里插入图片描述

注意:
如果当前方法为实例方法(或构造方法),那么JVM会默认创建一个this变量存储在index0处!

public class JvmTest {
    public JvmTest()
    {
        System.err.println("这是构造方法!");
    }
    public String sayHello(String name)
    {
        return name + "说Hello";
    }
}

在这里插入图片描述
所以,我们在方法中调用this,是因为JVM默认给我们创建了this变量,我们才可以直接调用。

注意:
不赋值(在代码块中赋值)的变量,在局部变量表中不显示,但局部变量表仍会为其预留位置。
在这里插入图片描述
可以看到,变量b并没有初始值,而变量c在代码块中赋值,而静态变量表中并没有显示。
在这里插入图片描述
但是请注意,局部变量表仍为其预留了位置,以便于变量使用。
在这里插入图片描述
只有显示的为变量赋值,才可以在局部变量表中显示。

变量槽的复用

在这里插入图片描述
查看我们此处代码可以发现,我们声明了变量a,b,c,但是局部变量表中只有this,a,c三个局部变量。
在这里插入图片描述
查看发现实际局部变量表长度也只有3(加上this本应由4个)。

此处原因就是JVM对变量槽有一个复用性为,当变量b超出其作用域后便不再生效,所以变量c直接占据了b的位置,所以局部变量表中会少一个位置。

总结:

局部变量表只对已确定一定有值的变量(且不在代码块中)和方法参数进行记录,在程序执行中得以直接使用,存储在量变槽中,如果是long和double,则需要占用两个变量槽,不足长度的数据则补全占满一个变量槽,实例方法和构造方法会自动创建this变量,并且如果代码块结束(作用域结束),jvm会对变量槽有一个复用的行为,以便于节省空间。

补充:
局部变量表中的变量也是重要的垃圾回收根节点,只要被局部变量表中直接或间接引用的对象都不会被回收。

此处知识点后续在进行解析~

谢谢大家观看,此文章均为本人学习笔记,如有错误,请指正~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值