在Java虚拟机规范中制定了虚拟机字节码执行引擎的概念模型,这个概念模型成为各种虚拟机执行引擎的统一外观.在不同的虚拟机实现里,执行引擎在执行java代码时可能会有解释执行和编译执行两种选择,也有可能两者兼备.
但所有的执行引擎的外观都是一样的:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果.
本章先讲解用于支持虚拟机进行方法调用和方法执行的数据结构:栈帧
栈帧存储了方法的局部变量表,操作数栈,动态连接,方法返回地址等信息.每一个方法从调用开始到执行完成的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程.
对于执行引擎来说,在活动线程中,只有位于栈顶的栈帧才是有效的,称为当前栈帧.与这个栈帧关联的方法是当前方法.执行引擎执行的所有字节码指令都只针对当前栈帧进行操作.
1,局部变量表:用于存放方法参数和局部变量
局部变量表的容量以变量槽(Slot)为最小单位,一个Slot能存放32位以内的数据类型,对于64位的数据类型,虚拟机会以高位对齐的方式为其分配两个连续的Slot空间.
2,操作数栈(LIFO)
在方法执行过程中,会有各种字节码指令往操作数栈写入和提取内容.
3,动态连接
每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接。我们知道class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用为参数。这些符号引用一部分会在类加载阶段或第一次使用的时候转化为直接引用,这种转化为称为静态解析,另外一部分将在每一次的运行期间转化为直接引用,这部分称为动态连接。
4,方法返回地址:一个方法执行后,有两种方法退出这个方法
一是正常退出,执行引擎遇到任意一个返回的字节码指令.这是可能会有返回值传递给上层调用者.返回指令也可能没有返回值.
二是异常退出,执行过程中遇到异常,并且这个异常没有在方法体内的到处理,无论是Java虚拟机内部产生的异常,还是代码中athrow字节码指令产生的异常,只要在本方法的异常表中没有搜索到匹配的异常处理器,就会导致方法退出.