《深入理解JAVA虚拟机》读书笔记系列之:
字节码执行引擎
功能:输入字节码文件,然后对字节码进行解析并处理,最后输出执行的结果。
实现方法:解释器直接解释或者即时编译生成本地代码,编译执行。
栈帧、局部变量表和运行期间操作数栈的交互
- 栈帧:方法调用和方法执行,随着方法调用产生和结束。存储了局部变量,操作数栈,动态链接,方法返回地址等信息。
- 局部变量表:
局部变量表是一组变量值的存储空间,用于存放方法参数和方法内部定义的局部变量。六种数据类型+reference+returnAddress
- 局部变量表:
- 存放方法参数和方法内部的局部变量,以slot为单位。
- 对于实例方法,0位存储的this;静态方法不会有this。
- 先分配方法参数,再分配局部变量。
- slot是可以复用的。这会对GC产生影响。
1 | public static void main(String[] args)() { |
- 操作数栈:存放运行方法期间,各个操作指令的数据。每次都是操作栈顶的数据。虚拟机在实现栈帧时候可以能会优化,比如两个栈帧出现重叠的部分,存放公用的数据。
动连接接:每个栈帧持有一个指向运行时常量池中该栈帧所属方法的引用,以支持方法调用中的动态连接。
*动态连接,运行期间转换为直接引用;静态链接,在类加载阶段或者第一次使用的时候就被转化为直接引用**。
返回地址:方法执行以后返回的地址。程序被调用的位置。
方法调用、静态分配和动态分派
方法调用:具体确定调用哪个方法。一切方法调用在Class文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址(也就是之前说的直接引用)。方法调用分为解析与分派。
解析调用
解析调用是静态过程:
在类加载的解析阶段,会将其中的一部分符号引用转化为直接引用,这种解析能够成立的前
提是:编译期可知,运行期不可变。
被invokestatic
和invokespecial
指令调用的方法,在解析阶段就确定。静态方法,私有方法,实例构造器,父类方法四种。再加上final
修饰的方法
分派调用
- 操作数栈:存放运行方法期间,各个操作指令的数据。每次都是操作栈顶的数据。虚拟机在实现栈帧时候可以能会优化,比如两个栈帧出现重叠的部分,存放公用的数据。。
动连接接:每个栈帧持有一个指向运行时常量池中该栈帧所属方法的引用,以支持方法调用中的动态连接。
*动态连接,运行期间转换为直接引用;静态链接,在类加载阶段或者第一次使用的时候就被转化为直接引用**。
返回地址:方法执行以后返回的地址。程序被调用的位置。
运行期动态委派:
实例方法,也称虚方法,因为重载和多态,需要运行时确定。
- 分派:静态分派和动态分派
静态分配:以来静态类型来定位方法执行版本。比如重载。依赖于传入什么静态类型。发生在编译阶段,因此一些资料归入了解析而不是解析。
静态分配:以来静态类型来定位方法执行版本。比如重载。依赖于传入什么静态类型。
1 | //Human 称为变量的“静态类型, |
动态分派:根据运行期的实际类型分配,比如重写。依赖于传入的实例对象类型。
- 单分派与多分派:分派思考的维度。