执行引擎是java虚拟机最核心的组合部分之一。“虚拟机”是相对于“物理机”的概念,这两种机器都有执行代码的能力,其区别是物理机的执行引擎是直接建立在处理器,硬件,操作数和操作系统层面上的,而虚拟机的执行引擎则是由自己实现的,因此可以自行定义指令集与执行引擎的结构体系,并且能够执行那些不被硬件直接支持的指令集格式。
运行时栈帧结构
栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈中的栈元素。栈帧存储了方法的局部变量表,操作数栈,动态链接和方法返回地址等信息。每个方法从弄调用开始至执行完成的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。
局部变量表: 是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。
操作数栈: 当一个方法开始执行的时候,这个方法的操作数栈是空的,咋方法执行的过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是出栈/入栈的过程
动态链接: 每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态链接。(Class文件的产量池中存在大量的符号引用,字节码中的方法调用指令就是以产量池中指向方法的符号引用作为参数。这些符号引用一部分会在类加载阶段或者第一次使用的时候就转化为直接引用,这种转化是静态解析。另一部分将在每一次运行期间转化为直接引用,这部分称为动态链接)
方法返回地址: 有正常退出和异常退出两种。在方法退出之后,都需要返回方法被调用的位置,程序才能继续执行,方法返回是可能需要在栈帧中保存一些信息,用来帮助回复它的上层方法的执行状态。
附加信息: 如与调试相关的信息
方法调用
方法调用不等同于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即哪一个方法被调用),暂时还不涉及方法内部的具体运行过程。
- 解析:调用目标在程序代码写好,编译器进行编译时就必须确定下来。这类方法的调用称为解析。
- 分派:
- 静态多分派(重载):需要根据静态类型+方法参数
- 动态单分派(重写):只需要判断方法的实际运行者
基于栈的字节码解释执行引擎
- 解释执行
- 基于栈的指令集与基于寄存器的指令集