JVM中的栈帧结构

栈帧(Stack Frame)是用于支持虚拟机进行方法调用方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈的栈元素。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用开始至执行完成的过程,都对应一个栈帧在虚拟机栈里面从入栈到出栈的过程。在编译程序代码的时候,栈帧中需要多大的局部变量表,多深的操作数栈都已经完全确定了,并且写入到方法表的Code属性之中,因此一个栈帧需要分配多少内存,不会受到程序运行期变量数据的影响,而仅仅取决于具体的虚拟机实现。

一个线程中的方法调用链可能会很长,很多方法都同时处于执行状态。对于执行引擎来说,在活动线程中,只有位于栈顶的栈帧才是有效的,称为当前栈帧,与这个栈帧相关联的方法称为当前方法。执行引擎运行的所有字节码指令都只针对当前栈帧进行操作,概念模型上,典型栈帧结构如图所示:
在这里插入图片描述
然后介绍一下栈帧中的局部变量表、操作数栈、动态连接和方法返回地址等各个部分的作用和数据结构。

1. 局部变量表

局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序编译为Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需要分配的局部变量表的最大容量

局部变量表的容量以变量槽(Slot)为最小单位,虚拟机规范中未说明它该有多大,只说了每个Slot都应该能存放一个boolean、byte、char、shoert、int、float、reference或returnAddress类型的数据。当然它们在Java中均占了32位以内,前面6种我们见得比较多,现在说一下reference类型。reference类型表示对一个对象实例的引用,虚拟机对它的长度和结构没有说明,但虚拟机实现至少都应当能通过这个引用做到两点:

  1. 从此引用直接或间接地查找到对象在Java堆中的数据存放的起始地址索引。(对象实例数据
  2. 此引用中直接或间接地查找对象所属数据类型在方法去中的存储的类型信息。(类型数据

而第8种类型returnAddress已经很少见了。对于64位的数据类型,虚拟机会以高位对齐的方式为其分配两个连续的Slot空间,Java中明确的64位数据只有long和double两种。虚拟机通过索引定位的方式使用局部变量表,索引值的范围是从0开始至局部变量表最大的Slot数量。即如果访问的是32位变量,则索引n就代表访问第n个Slot,64位的则是第n和n+1个Slot。对于两个相邻的共同存放一个64位数据的两个Slot,不允许采用任何方式单独访问其中的某一个,如果遇到有这种操作的字节码序列,会在类加载的校验阶段抛出异常。

方法执行时,虚拟机是使用局部变量表完成参数值到参数变量列表的传递过程的,如果执行的是实例方法,那局部变量表中第0位索引的Slot默认是用于传递方法所属对象实例的引用,在方法中可以通过关键字“this”来访问这个隐含的参数。其余参数则按照参数表顺序排列,占用从1开始的局部变量Slot,参数表分配完毕后,再根据方法体内部定义的变量顺序和作用域分配其余的Slot。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值