虚拟机字节码执行引擎
一、运行时栈帧结构
1、栈帧(Stack Frame)是用于支持虚拟机进行调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈(Virtual Method Stack)的栈元素,栈帧存储了方法的局部变量表,操作数栈,动态连接和方法返回地址等信息。
2.局部变量表(Local Virtual Table)
局部变量表是一组变量值存储空间,用于存放参数和方法内部定义的局部变量。
局部变量表的容量以变量曹(Variable Slot)为最小单位。slot应该能存放一个Boolean,byte,char , short,int , float,reference或returnAddress类型的变量的数据。
虚拟机通过索引定位的方式使用局部变量表,索引值得范围是从0开始至局部变量表最大的slot数量。
在方法执行时,虚拟机是使用局部变量表来完成参数到参数列表的传递过程。
3.操作数栈(Operand Stack)
操作数栈也常称为操作站,它是一个后入先出(LILO)栈。
当一个刚刚开始执行的时候,这个方法的操作数栈是空的,在方法的执行过程中会有各种字节码指令往操作数栈中写入和提取内容也就是出栈和入栈操作。
4.动态连接
每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持调用过程中的动态连接(Dynamic Linking)。
5.方法返回地址
当一个方法开始执行引擎遇到任何一个方法返回的字节码指令,这时候可能会有返回值传递给上层的方法调用者,是否有返回值和返回值的类型将根据遇到何种方法返回指令来决定,这种退出方法的方式称为正常完成出口。
另一种退出的方式是,在方法中执行过程中遇到了异常并且这个异常没有在方法体内部得到处理,无论在Java虚拟机内部产生的异常,还是代码中使用athrow字节码指令产生的异常,只要在本方法的异常表中没有搜索到匹配的异常处理器,就会导致方法退出,这种退出方式称为异常完成出口。
二、方法调用
解析调用一定是一个静态的过程,在编译期间就完全确定,在类装载的解析阶段就会把涉及的符号引用全部转换为可确定的直接引用,不会延迟到运行期再去完成。
还有一种方法调用是分派调用。