概述:
“虚拟机”是一个相对于“物理机”的概念,这两种机 器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层 面上的,而虚拟机的执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定制指令集与执 行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式。
运行时栈帧结构:
方法是java虚拟机最基本的执行单元。栈帧是支持虚拟机进行方法调用的数据结构,也是虚拟机运行时数据区中的虚拟机栈。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。
局部变量表:是一组变量值的存储空间,用于存放方法参数和方法内部定义 的局部变量
局部变量表的容量以变量槽(Variable Slot)为最小单位,每个变量槽都应该能存放一个boolean、 byte、char、short、int、float、reference或returnAddress类型的数据。
对于64位的数据类型,Java虚拟机会以高位对齐的方式为其分配两个连续的变量槽空间。当一个方法被调用时,Java虚拟机会使用局部变量表来完成参数值到参数变量列表的传递过程, 即实参到形参的传递。
当⼀个⽅法被调⽤时,Java虚拟机会使⽤局部变量表来完成参数值到参数变量列表的传 递过程, 即实参到形参的传递。如果执⾏的是实例⽅法(没有被static修饰的⽅法),那局 部变量表中第0位索引的变量槽默认是⽤于传递⽅法所属对象实例的引⽤,在⽅法中可以 通过关键字“this”来访问到这个隐含的参数。
操作数栈:
操作数栈(Operand Stack)也常被称为操作栈,它是一个后入先出(Last In First Out,LIFO) 栈。当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的。让下⾯栈帧 的部分操作数栈与上⾯栈帧的部分局部变量表重叠在⼀起,这样做不仅节约了⼀些空间, 更重要的是在进⾏⽅法调 ⽤时就可以直接共⽤⼀部分数据,⽆须进⾏额外的参数复制传递了。
动态连接:
每个栈帧都包含⼀个指向运⾏时常量池中该栈帧所属⽅法的引⽤,持有这个引⽤是为了⽀ 持⽅法调⽤过程中的动态连接(Dynamic Linking)。通过第6章的讲解,我们知道Class⽂ 件的常量池中存有⼤量的符号引⽤,字节码中的⽅法调⽤指令就以常量池⾥指向⽅法的符 号引⽤作为参数。这些符号引⽤⼀部分会在类加载阶段或者第⼀次使⽤的时候就被转化为 直接引⽤,这种转化被称为静态解析。 另外⼀部分将在每⼀次运⾏期间都转化为直接引 ⽤,这部分就称为动态连接。