目录
1.什么是java虚拟机栈?
Java虚拟机栈(Java Virtual Machine Stack)采用栈的数据结构来管理方法调用中的基本数据,先进后出(First In Last Out),每调用一个方法,会产生一个该方法的栈帧(Stack Frame),并将该栈帧入栈。
2.栈帧
Java虚拟机栈的栈帧中主要包含三方面的内容:
-
局部变量表
-
操作数栈
-
帧数据
2.1栈帧——局部变量表
局部变量表的作用是在方法执行过程中存放所有的局部变量。局部变量表分为两种,一种是字节码文件中的,另外一种是栈帧中的也就是保存在内存中的。栈帧中的局部变量表是根据字节码文件中的内容生成的。
栈帧中的局部变量表是一个数组,数组中每一个位置称之为槽(slot) ,long和double类型占用两个槽,其他类型占用一个槽。调用方法分为静态方法和实例方法,需要注意的是,如果调用的是实例方法,数组序号为0的位置存放的是this,指的是当前调用方法的对象,运行时会在内存中存放实例对象的地址。
2.2栈帧——操作数栈
操作数栈是栈帧中虚拟机在执行指令过程中用来存放中间数据的一块区域。他是一种栈式的数据结构,如果一条指令将一个值压入操作数栈,则后面的指令可以弹出并使用该值。在编译期就可以确定操作数栈的最大深度,从而在执行时正确的分配内存大小。
2.3栈帧——帧数据
帧数据主要包含动态链接、方法出口、异常表的引用。
2.3.1动态链接
当前类的字节码指令引用了其他类的属性或者方法时,需要将符号引用(编号)转换成对应的运行时常量池中的内存地址。动态链接就保存了编号到运行时常量池的内存地址的映射关系。
2.3.2方法出口
方法出口指的是方法在正确或者异常结束时,当前栈帧会被弹出,同时程序计数器应该指向上一个栈帧中的下一条指令的地址。所以在当前栈帧中,需要存储此方法出口的地址(上一个栈帧中的下一条指令的地址)。
2.3.3异常表
异常表存放的是代码中异常的处理信息,包含了异常捕获的生效范围以及异常发生后跳转到的字节码指令位置。