虚拟机字节码执行引擎

运行时栈帧结构。

每个方法都有个栈帧,用来存储局部变量,操作数栈,方法入口,动态连接等。方法执行的过程就是栈帧入栈到出栈的过程。每个线程的运行时栈中可能有很多栈帧,只有栈顶的栈帧是有效的,成为当前栈帧,这个栈帧关联的方法称为当前方法,引擎所运行的字节码指令只对当前栈帧进行操作。

局部变量表

局部变量表以变量槽(Variable slot)为基本单位,每个变量槽占32位。用于存储方法参数和方法内部定义的局部变量。slot的大小随系统变化而变化。在64位系统中,slot的大小是64位,但是虚拟机仍会使用移位和补齐的手段来让slot看起来和32位虚拟机中的一致,即虽然slot占用了64位空间,但是只能使用其中的32位。这一点也是java代码在不同系统上运行结果相同的保证。
对于64位数据类型,则用两个slot来存储。由于局部变量表是在线程私有的区域,所以读写两个连续的slot是否是原子操作并不会导致数据安全问题

局部变量表的使用方式:通过索引定位来使用局部变量表。对于32位数据类型,索引n表示使用第n个slot;对于64位的数据类型,索引n表示使用第n和n+1个slot。对于实例方法,第0位索引是当前实例的引用,可以用this来访问这个参数。

局部变量表中的slot是可重用的。在局部变量所有的slot都被占用的情况下,即使这些slot不会再被使用了,JVM也不一定会清理掉这部分内存,只有当新的变量没有空闲的slot可用时,GC root才会打断关联(可以顶定义一个无意义变量,或者把手动把这些变量设置为空),进而让JVM清理掉之前占用的slot。

操作数栈(操作栈)

操作数栈具有后入先出的特性,最大栈深度在编译时确定。其中的元素可是任意的Java数据类型。在方法执行的过程中,会有字节码执行向栈中写入和提取内容。
虚拟机栈中,每一个操作数栈都是独立的,但是有的虚拟机可以进行一些优化,让两个栈有一些公共的部分,这样可以避免数据复制的操作,加快运行速度。

动态链接

类中的部分符号引用会在每次运行的时候转化为直接引用,这部分称为动态链接。

方法返回地址

正常完成出口:引擎遇到任意一个方法的字节码返回地址,则把返回地址传递给调用者,
异常完成出口:方法执行遇到了一个异常,方法内部找不到解决的办法,就会导致方法退出。
无论以什么方式退出,程序都要回到调用方法的位置,以便继续执行下面的代码。一般来说,正常退出的时候,调用者的PC计数器值就作为返回的地址。

附加信息

虚拟机规范允许具体的虚拟机添加一些规范里没有描述的信息到栈帧中去,例如与调试相关的信息,这部分信息完全取决于具体的虚拟机实现。一般会把动态连接,方法返回地址,附加信息统称为栈帧信息。

你可能感兴趣的:(虚拟机字节码执行引擎)