万互网站建站免费域名解析平台
第8章 虚拟机字节码执行引擎
8.1 概述
解释执行,编译执行,或混合执行
8.2 运行时栈帧结构
一个方法对应一个栈帧,一个方法的出入栈代表运行情况。
程序的字节码指令只针对于当前栈帧生效。
栈占用的内存在运行前便已确定。
8.2.1 局部变量表
存储局部变量与方法参数
8.2.2 操作数栈
各种字节码指令在运行时在栈中出入栈来实现运算。
两个栈帧会互享一部分数据(调用时局部变量为调用方法的参数等
8.2.3 动态连接
略
8.2.4 方法返回地址
正常退出后将返回值传给调用栈帧即可
异常退出无返回值,且当前线程停止运行
8.3 方法调用
8.3.1 解析
类加载时可解析确定唯一版本的方法:
1>静态方法
2>构造方法
3>私有方法
4>父类方法
5>final方法
8.3.2 分派
1>静态分派
Human【静态类型】 hm = x > y ? new Man() : new Woman()【实际类型】;
【一个对象的静态类型是编译期可知的,而实际类型在运行期间才可知晓】
【方法重载时通过静态类型确定调用方法(编译器可确定)】
【确定重载方法会自动转换,直到找不到为止】
转换顺序:char > int > long > float > double > 接口 > 父类(由下到上)
2>动态分派
方法重写由实际类型确定
字段不具有多态性,只会使用当前类的,没有才会找父类的,但子类覆盖父类。
直接在外部调用字段根据静态类型调用。
3>单分派与多分派
Java是静态多分派,动态但分派的。
【单分派与多分派区别是分派时的宗量数。
宗量:方法接收者(this)与参数】
4>虚拟机动态分派的实现
通过建立虚方法表来减少搜索元数据,子类未重写的父类方法在虚方发表中的入口为父类入口地址,重写过即为子类入口地址。
8.4 动态类型语言支持
8.4.1 动态类型语言
无静态类型,只有实际类型
8.4.2 Java与动态类型
JVM原本不太支持动态类型
8.4.3 java.lang.invoke包
可以动态调用方法(字节码层面)
8.4.4 invokedynamic指令
略
8.5 基于栈的字节码解释执行引擎
8.5.1 解释执行
JVM处理字节码(编译器输出)
8.5.2 基于栈的指令集与基于寄存器的指令集
栈运行速度不如寄存器,但代码紧凑,编译器实现简单。
解释运行时,因有大量出入栈操作,导致栈指令运行慢,但即时编译后的汇编指令便没有这种问题了。
8.5.3 基于栈的解释器执行过程
略【虚拟机执行时会对执行过程做一系列优化】