Execution Engine是虚拟机的核心组成之一
虚拟机和物理机的区别是什么?
这两种机器都有代码执行的能力,但是:
- 物理机的执行引擎是直接建立在处理器、硬件、指令集和操作系统层面的。
- 虚拟机的执行引擎是自己实现的,因此可以自行制定指令集和执行引擎的结构体系,并且能够执行那些不被硬件直接支持的指令集格式。
Java虚拟机规范指定了虚拟机字节码执行引擎的概念模型,提供了统一Facade。不同的虚拟机实现里,执行的时候,可能会有解释执行、编译执行两种,或者两者兼备
运行时栈帧结构
栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构, 存储了方法的
- 局部变量表
- 操作数栈
- 动态连接
- 每个栈帧都包含一个指向运行时常量池中,该帧所属方法的引用,以支持动态连接
- 方法返回地址
每一个方法从调用开始到执行完成的过程,就对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程
方法调用
方法调用唯一的任务是确定被调用方法的版本(调用哪个方法),暂时还不涉及方法内部的具体运行过程。
Java的方法调用,有什么特殊之处?
Class文件的编译过程不包含传统编译的连接步骤,一切方法调用在Class文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址。这使得Java有强大的动态扩展能力,但使Java方法的调用过程变得相对复杂,需要在类加载期间甚至到运行时才能确定目标方法的直接引用。
解析
“编译期可知,运行期不可变”,这类方法的调用叫“解析”
- 静态方法
- 私有方法
分派
-
静态分派
- 依赖静态类型(编译时确定)来定位方法的执行版本的分派动作,叫做静态分派
- 方法重载
-
动态分派
- 在运行期根据实际类型确定方法执行版本的分派,叫做动态分派
- 方法重写(invokevirutal把常量池中的方法的符号引用解析到不同的直接引用上)
单分派和多分派
- 静态多分派
- 动态单分派
Java虚拟机调用字节码指令有哪些?
- invokestatic:调用静态方法
- invokespecial:调用实例构造器方法、私有方法和父类方法
- invokevirtual:调用所有的虚方法
- invokeinterface:调用接口方法
动态语言支持
JDK 1.7增加的指令 invokedynamic
字节码解释执行引擎
虚拟机是如何执行方法里面的字节码指令的?
- 解释执行(通过解释器执行)
- 编译执行(通过即时编译器JIT产生本地代码)<