java虚拟机基础知识(六):虚拟机字节码执行引擎
一:概述
执行引擎:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果
二: 运行时栈帧结构
栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构
栈帧存储了局部变量表,操作栈,动态连接,返回地址等
1) 局部变量表
局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量,最小单位是变量槽(Variable Slot),没有明确指出大小,只说到能存放32位内的长度boolean,byte,char,short,int,float,reference(表示对一个对象实例的引用),或returnAddress(指向字节码指令的地址)
通过索引定位的方式使用局部变量表,索引值的范围从0开始到局部变量表最大的slot数量。若执行的是实例方法(非static方法),那局部变量表中第0位索引的slot默认是用于传递方法所属对象实例的引用
2) 操作数栈
后入先出,同局部变量表,32位数据类型占的栈容量为1,64位数据类型占的栈容量为2。操作数栈中元素的数据类型必须与字节码指令的序列严格匹配
3) 动态连接
静态解析:部分符号引用会在类加载阶段或第一次使用的时候就转化为直接引用
动态解析:部分符号引用在每一次运行期间转化为直接引用
4) 方法返回地址
只有两种退出方法的方式:
- 1)正常完成出口:执行引擎遇到任意一个方法返回的字节码指令,调用者的计数器可以作为返回地址
- 2)异常完成出口:遇到异常,且没有在方法体中得到处理,返回地址要通过异常处理器来确定
三、方法调用
方法调用阶段唯一的任务是确定被调用方法的版本(即调用哪一个方法),暂时还不涉及方法内部的具体运行过程
1) 解析
直接引用—解析成立前提:方法在程序真正运行之前就有一个可确定的调用版本,并且这个方法的调用版本在运行期间是不可改变的
非虚方法:在类加载的时候就会把符号引用解析为该方法的直接引用,能被invokestatic和incokespecial指令调用,可以在解析阶段中确定唯一的调用版本,有静态方法,私有方法,实例构造器,父类方法,+final方法4类
2) 分派
1、静态分派
静态分派:所有依赖静态类型来定位方法执行版本的分派动作,典型应用是方法重载
2. 动态分派
动态分派:运行期根据实际类型确定方法执行版本的分派过程,应用--重写
3. 单分派与多分派
单分派:根据一个宗量对目标方法进行选择;
多分派:根据多于一个宗量对目标方法进行选择
JAVA语言的动态分派属于单分派类型
4. 虚拟机动态分派的实现
- 优化频繁搜索的常用“稳定优化”手段:为类在方法去建立一个虚方法表,使用虚方法表索引来代替元数据查找以提高性能
- 非稳定激进优化手段:内联缓存,基于“类型继承关系分析”技术的守护内联