一个栈帧需要分配多少内存,在编译Java源代码的时候已经决定,不会受运行期变量数据的影响,仅仅

局部变量表

Local Variable Table 是一组变量值的存储空间,用于存放方法参数和方法内部定义的局部变量。方法的Code属性的max_locals数据项中确定了该方法所需分配的局部变量表的最大容量。

操作数栈

Operand Stack,是一个后入先出的栈。最大深度在编译时写入Code属性的max_stacks数据项中。
方法开始执行的时候,操作数栈是空的,在执行过程中,会有各种字节码指令往操作数栈中写入和提取内容,即进行出站和入栈操作。
在概念模型中,不同的栈帧之间是完全独立的,大多数虚拟机的实现中会有优化处理,栈帧有重叠。下面栈帧的部分操作数栈与上面栈帧的部分就不变量表重叠在一起,作用:1. 节约空间 2. 共用数据,减少复制传递。

动态链接

每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有该引用是为了支持方法调用过程中的动态链接。
这些符号引用一部分会在类加载阶段或者第一次使用时候被转化为直接引用,成为静态解析。另外一部分在每一次运行期间转化为直接引用,称为动态连接。

方法返回地址

一个方法开始执行以后,只有两种方式退出这个方法。

  1. 执行引擎遇到任意一个方法返回的字节码指令,此时,可能会有返回值传递给上层的方法调用者,这是正常调用完成。
  2. 在方法执行过程中遇到异常,并且这个异常在方法内部没有得到妥善处理。不论是Java虚拟机内部产生的异常还是代码中使用athrow字节码产生的异常,只要方法的异常表中没有搜索到匹配的异常处理器,就会导致方法退出,称为异常调用完成。不会给上层调用者返回任何值。

方法退出就是把当前栈帧出栈,因此退出时会进行下列操作:

  1. 恢复上层方法的局部变量表和操作数栈
  2. 返回值压入调用者栈帧的操作数栈中
  3. 调整PC计数器的值以指向方法调用指令后面的一条指令

额外附加信息

调试、性能收集相关的信息。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐