深入理解JVM(四)-执行引擎

        本文章是根据《深入理解Java虚拟机》一书,并参考网上其他文档进行的系统性的和简单容易理解的方式进行的整理。

一、执行引擎

        执行引擎是Java最核心的组成部分之一,具有执行代码的能力,如下图所示:

1、运行时栈帧结构

        栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区虚拟机栈的栈元素。栈帧存储了局部变量表、操作数栈、动态链接、方法返回地址等信息。执行引擎所运行的字节码文件都只对当前栈帧进行操作。栈帧中的局部变量表、操作数栈等的大小已经在编译好的字节码文件(也可以是网络中的字节码信息)中指定好。

        ①局部变量表。一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。最大容量在Class文件的属性中指定。局部变量表的变量需要手动赋初值。

        ②操作数栈。 操作数栈也常被称为操作栈,它是一个后入先出栈,最大容量在Class文件的属性中指定。

        ③动态链接。每个栈帧都包含一个指向运行时常量池的该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接。

        ④方法返回地址。当一个方法被执行后,有两种方式退出这个方法,一种是正常完成出口(方法遇到返回指令),一种是异常完成出口(JVM虚拟机内部产生异常)。

        ⑤附加信息。虚拟机规范中没有明确要求的其他供应商自行添加的信息。

2、方法调用

        方法调用不等同于方法的执行,Class文件中存储的都是符号引用(给Java带来更强大的动态扩展能力),需要在类加载期间甚至到运行期间才能确定目标方法的直接引用,所以使得Java的调用过程变得相对复杂。

        ①解析:在编译期将方法的符号引用转变为直接引用,符合”编译器可知,运行期不可变“的要求,符合这个要求的主要有静态方法和私有方法(因为这两类方法不可能通过继承或别的方式写出其他版本),其中静态方法时通用的,而私有方法是私有的。主要是针对非虚方法。补充概念:

                虚方法:能被重写的方法,一般指的是实例方法。

                非虚方法:不能被重写的方法,指的是构造方法、静态方法、私有方法和final修饰的方法。

        ②分派:Java虚拟机确定正确的目标方法的过程。分派与解析不是互斥的动作,而是在不同层次去筛选和确定目标方法的过程。主要是针对虚方法

                静态分派:在代码编译期间通过静态类型(方法参数的接收类型,而不是实际类型)来定位方法执行版本的分派动作。主要体现在方法的重载。需要注意的是,在重载情况下,编译器虽然能确定出方法的重载版本,很多情况下这个重载版本并不是“唯一”的,往往只能确定一个更加适合的版本。如下图,当调用sayHello(‘a’)时,编译器会在下面三个方法中选择一个合适的方法:

                动态分派:主要是体现了重写的特性。大概步骤如下:

                        第一步:找到对象的实际类型;

                        第二步:如果在对象中找到同名的方法并校验访问权限,如果通过则返回这个方法的直接引用,查找过程结束。

                        第三步:如果第二步没找到则去其父类中查找同名的方法和进行权限验证,如果通过则返回方法的直接引用,查找过程结束。

                        第四步:如果没有找到合适的方法,则抛出java.lang.AbstractMethodError异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值