JVM虚拟机深入理解----虚拟机字节码执行引擎

代码编译的过程中,从本地机器码转变为字节码,不仅是存储格式发展的一小步,更是编程语言发展的一大步。

1.运行时栈帧结构

栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)的栈元素。栈帧存储了方法区中的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用开始至执行完成的过程,都对应这一个栈帧在虚拟机里面从入栈到出栈的过程。

JVM虚拟机深入理解----虚拟机字节码执行引擎_第1张图片

 1.1局部变量表

局部变量表(Local Variable Table)是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。

局部变量表的容量以变量槽(Variable Slot)为最小最小单位,虚拟机里面规范的说到每个slot都应该能存放一个Boolean、byte、int、float、char、short、reference或returnAddress类型的数据。为什么是这八种呢?主要原因是因为slot只能存放32位以下的数据类型,所以像double是8个字节(64位),无法存放到变量槽里面。

解释一下:

reference:表示对一个对象实例的引用;

returnAddress:它是为字节码指令jsr、jsr_w服务的,指向一条字节码指令的地址。现在已经很少使用。

前面提到了,slot只能存储32位的,那long和double又是怎么存储的呢?对于64位的数据类型,虚拟机以高位对齐的方式为其分配两个连续的slot空间。

1.2操作数栈

操作数栈(operand stack)也常称为操作栈,它是一个先进后出(Last  Of First Out,LOFO)栈。同局部变量表一样,但是操作数栈的每一个元素可以是任意java数据类型。32位数据类型占一个栈容量,64位数据类型占两个栈容量。

1.3动态连接

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

在Class文件的常量池中存在大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用作为参数。这个符号引用一部分会在类加载阶段或者第一次使用的时候就转化成为直接引用,这个转换称为静态解析。另外一部分将在每一次运行期间转化为直接引用,这部分称为动态连接。

1.4方法返回地址

当一个方法执行后,只有两种方式退出这个方法:

1)执行引擎遇到一个方法的返回字节码指令,这时候可能会有返回值传递给上层的方法调用者,是否有返回时和返回值的类型根据遇到何种方法返回指令来决定,这种退出方法称为正常完成出口(normal method invocation completion)

2)在方法执行的时候遇到了异常,并且这个异常没有在方法体得到处理,而且在本方法的异常表中没有搜索到匹配异常处理器,就会导致方法退出,这个退出方式称为异常完成出口(abrupt method invocation completion)。该方式不会给调用者返回任何参数。

1.5附加信息

虚拟机规范允许具体的虚拟机实现增加一些规范中没有描述的信息到栈帧之中。

 

你可能感兴趣的:(虚拟机深入理解)