- 运行时栈结构
- 栈帧是虚拟机进行方法 调用和方法执行的数据结构。它是虚拟机栈的栈中元素。主要由以下四种信息:(1)局部变量表 (2)操作数栈 (3)动态链接 (4)方法返回地址
- 栈帧的大小是在编译时就可以确定的,比如需要多大的局部变量表,操作数栈有多深等等。因此,一个栈帧需要分配多少内存,只受到虚拟机的具体实现影响。
- 符合平时运行逻辑一样,只有栈顶的栈帧元素才有效果,这个被称为当前栈帧,与当前栈帧相关联的方法被称为当前方法
- 局部变量表
- 定义:局部变量表是一组变量值的存储空间,包括存放方法的形参列表以及方法内的局部变量。
- 容量单位:局部变量的基本单位是变量槽(Variable Slot)。这个基本单位的大小和虚拟机是32/64位有关。一个slot至少能存放32位的数据,比如byte/boolean(8位),int(32位),short(16位),float(32)。以及reference(对象实例的引用),returnAddress(现已不太常用,古老版本曾用来处理异常,现已用异常表代替)
- 对于64位的数据,虚拟机会以高位对齐的方式为其分配两个连续的slot空间
- 使用方式:虚拟机通过索引定位的方式使用局部变量表。索引0代表实例方法对应类对象的实例(通过this关键字可以访问);接下来从1开始是按形参列表顺序的形参;最后是方法内定义的局部变量。
- 特点:局部变量表中,为了节省空间,Slot空间是可以进行复用的。
- 操作数栈
- 特点:操作数栈中的每一个元素可以是任意的java数据类型,只是32位的占1个,64位占两个
- 内容:(1)java数据类型 (2)算术运算符 (3)调用其他方法时的参数传递
- 其他:在概念模型中,我们知道虚拟机栈是线程隔离的,操作数栈按理说也是隔离的。但是在大多数虚拟机的实现中进行了优化处理,令两个栈帧出现了一部分重叠(上一个栈帧的局部变量表共享区域和下一个栈帧的操作数栈共享区域)
- 动态连接
- 栈帧中包含一个所属方法对应常量池中的引用,为了方便在运行期将符号引用转化为直接引用
- 方法返回地址
- 原因:方法退出时只有两种可能:1、return 2、抛出异常
- 操作:将当前栈帧出栈(即结束当前方法),恢复上层方法的局部变量表和操作数栈/将返回值(如果有的话)压入调用方法栈帧的操作数栈