java虚拟机结构(概览三)

java虚拟机结构(概览三)

1、栈帧

栈帧(frame)是用来存储数据和部分过程结果的数据结构,同时也用来处理动态链接、方法返回值和异常分派。 栈帧随着方法的调用而创建,随着方法结束而销毁——无论方法是正常完成还是异常完成(抛出了在方法内未被捕获的异常)都算作方法结束。栈帧的存储空间由创建它的线程分配在java虚拟机栈之中,每一个栈帧都有自己的本地变量表和指向当前方法所属的类的运行时常量池的引用。 栈帧中还允许携带与java虚拟机实现相关的一些附加信息,例如,对程序调试提供支持的信息。 本地变量表和操作数栈的容量在编译期确定,并通过相关方法的code属性保存及提供给栈帧使用。因此,栈帧数据结构的大小仅仅取决于java虚拟机的实现,实现者可以在调用方法时给它们分配内存。 在某条线程执行过程中的某个时间点上,只有目前正在执行的那个方法的栈帧是活动的。这个栈帧称为当前栈帧(current frame),这个栈帧对应的方法称为当前方法,定义这个方法的类称为当前类。对局部变量表和操作数栈的各种操作,通常都指的是对当前栈帧的局部变量表和操作数栈所进行的操作。

1.1、局部变量表

每个栈帧内部都包含一组称为局部变量表的变量列表。栈帧中局部变量表的长度由编译器决定,并且存储于类或接口的二进制表示之中,即通过方法的code属性保存及提供给栈帧使用。 一个局部变量可以保存一个类型为boolean、byte、char、short、int、float、reference或returnAddress的数据。两个局部变量可以保存一个类型为long或double的数据。 局部变量使用索引来进行定位访问。首个局部变量的索引值为0。局部变量的索引值是个整数,它大于等于零,且小于局部变量表的长度。 long和double类型的数据占用两个连续的局部变量,这两种类型的数据值采用两个局部变量中较小的索引值来定位。 java虚拟机使用局部变量表来完成方法调用时的参数传递。当调用方法类是,它的参数将会依次传递到局部变量表中从0开始的连续位置上。当调用实例方法时,第0个局部变量一定用来存储该实例方法所在对象的引用(即java语言中的this关键字)。后续的其他参数将会传递至局部变量表中从1开始的连续位置上。

1.2、操作数栈

每个栈帧内部都包含一个称谓操作数栈的后进先出栈。栈帧中操作数栈的最大深度由编译期决定,并且通过方法的code属性保存及提供给栈帧使用。 栈帧在刚刚创建时,操作数栈是空的。java虚拟机提供了一些字节码指令来从局部变量表或对象实例的字段中复制常量或变量值到操作数栈中,也提供了一些字节码指令用于从操作数栈取走数据。操作数据以及把操作结果重新入栈。在调用方法是,操作数栈也用来准备调用方法的参数以及接收方法返回结果。 操作数栈中的数据必须正确的操作。在任意时刻,操作数栈都会有一个确定的栈深度,一个long或者double类型的数据会占用两个单位的栈深度,其他数据类型则会占用一个单位的栈深度。

1.3、动态链接

每个栈帧内部都包含一个指向当前方法所在类型的运行时常量池的引用,以便对当前方法的代码实现动态链接。在class文件里面,一个方法若要调用其他方法,或者访问成员变量,则需要通过符号引用来表示,动态链接的作用就是将这些以符号引用所表示的方法转换为对实际方法的直接引用。类加载的过程中将要解析尚未被解析的符号引用,并且将对变量的访问转化为变量在程序运行时,位于存储结构中的偏移量。

1.4、方法调用的正常完成

方法调用的正常完成是指在方法的执行过程中,没有抛出任何异常——包括直接从java虚拟机中抛出的异常以及在执行时通过throw语句显式抛出的异常。如果当前方法调用正常完成,它很可能返回一个值给调用它的方法。方法正常完成发生在一个方法执行过程中遇到了方法返回的字节码指令是,使用哪种返回指令取决于方法返回值的数据类型。 在这种场景下,当前栈帧承担着恢复调用者状态的责任,包括恢复调用者的局部变量表和操作数栈,以及正确递增程序计数器,以跳过刚才执行的方法调用指令等。调用者的代码会在被调用方法的返回值压入调用者栈帧的操作数栈后,会继续执行。

1.5、方法调用异常完成

方法调用异常完成是指在方法的执行过程中,某些指令导致了java虚拟机抛出异常,并且虚拟机抛出的异常在该方法中没有办法处理,或者在执行过程中遇到athrow字节码指令并显式地抛出异常,同时在该方法内部没有捕获异常。如果方法异常调用完成,那一定不会有方法返回值返回给其调用者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值