JVM读书笔记(五)——虚拟机字节码执行引擎

5.1 概述

在Java虚拟机规范中制定了虚拟机字节码执行引擎的概念模型,这个概念模型成为各种虚拟机执行引擎的统一外观。在不同的虚拟机实现里面,执行引擎在执行Java代码的时候可能会有解释执行和编译执行两种选择,也可能两者兼备,甚至还可能会包含几个不同级别的编译器执行引擎。但从外观上看,所有的Java虚拟机的执行引擎都是一致的:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果。

5.2 运行时栈帧结构


5.2.1 局部变量表

局部变量表是一组变量值存储空间,用于存放方法参数和和方法内部定义的局部变量。在Java程序编译为Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需要分配的局部变量表的最大容量。

5.2.2 操作数栈

操作数栈也称为操作栈,它是一个后入先出栈。同局部变量表一样,操作数栈的最大深度也是在编译的时候写入到Code属性的max_stacks数据项中。操作数栈的每一个元素可以是任意的Java数据类型,包括long和double。32位数据类型所占的栈容量为1,64位数据类型所占的栈容量为2。在方法执行的任何时候,操作数栈的深度都不会超过在max_stacks数据项中设定的最大值。

5.2.3 动态连接

每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接。Class文件中存在大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用作为参数。这些符号引用一部分会在类加载阶段或第一次使用的时候就转化为直接引用,这种转化成为静态解析。另外一部分将在每一次运行时期转化为直接引用,这部分称为动态连接。

5.2.4 方法返回地址

无论采用何种方式退出,在方法退出之后,都需要返回到方法被调用的位置,程序才能继续执行,方法返回时可能需要在栈帧中保存一些信息,用来帮助恢复它的上层方法的执行状态。一般来说,方法正常退出时,调用者的PC计数器的值,可以作为返回地址,栈帧中很可能会保存这个计数器值。而方法异常退出时,返回地址是要通过异常处理器表来确定的,栈帧中一般不会保存这部分信息。

5.3 方法调用

方法调用并不等同于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本,暂时还不涉及方法内部的具体运行过程。在程序运行时,进行方法调用是最普遍的操作,但Class文件的编译过程中不包含传统编译中的连接步骤,一切方法调用在Class文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局的入口地址。这个特性给Java带来了更强大的动态扩展能力,但也使Java方法调用过程变得复杂,需要在类加载期间,甚至到运行期才能确定目标方法的直接引用。

5.3.1 解析

所有方法调用中的目标方法在Class文件里面都是一个常量池中的符号引用,在类加载的解析阶段,会将其中的一部分符号引用转化为直接引用,这种解析能成立的前提是:方法在程序真正运行之前就有一个可确定的调用版本,并且这个方法的调用版本是在运行期不可改变的。换句话说,调用目标在程序代码写好、编译器进行编译时就必须确定下来。这类方法的调用称为解析。

5.3.2 分派

1.静态分派

所有依赖静态类型来定位方法执行版本的分派动作称为静态分派。静态分派的典型应用是方法重载。静态分派发生在编译阶段,因此确定静态分派的动作实际上不是由虚拟机来执行的。编译器虽然能确定出方法的重载版本,但很多情况下这版本并不唯一,往往只能确定一个更合适的版本。这种模糊的结论比较罕见,主要原因是字面量不需要定义,所以字面量没有显式的静态类型,它的静态类型只能通过语言上的规则去理解和推断。

2.动态分派

在运行期根据实际类型确定方法执行版本的分派过程称为动态分派。

3.单分派与多分派

方法的接收者与方法的参数统称为方法的宗量。根据分派基于多少种宗量,可以将分派划分为单分派与多分派。

4.动态分派的实现

由于动态分派是非常频繁的动作,而动态分派的方法版本选择过程需要运行时在类方法的元数据中搜索合适的目标方法,因此在虚拟机的实际实现中基于性能的考虑,大部分实现都不会真正进行如此频繁的搜索。面对这种情况,最常用“稳定优化”手段就是为类在方法区中建立一个虚方法表,使用虚方法表索引代替元数据查找以提高性能。

5.3.3 动态类型语言支持

动态类型语言的关键特征就是它的类型检查主题是在运行期而不是编译期,常用的包括:JS,Python,PHP,Ruby等。

5.4 基于栈的字节码解释执行引擎
5.4.1 解释执行


5.4.2 基于栈与基于寄存器的指令集

基于栈的指令集架构,指令流中的指令大部分都是零地址指令,它们依赖操作数栈进行工作。基于寄存器的指令集,最典型的就是x86的二地址指令集,也就是我们主流PC中直接支持的指令集架构。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值