0、栈帧结构图
栈帧(Stack Frame)是用来支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈的栈元素。栈帧(Stack Frame)存储了方法的局部变量表、操作数栈、动态连接、和方法返回地址、额外的附加信息。每个方法在执行的同时,都会创建一个栈帧(Stack Frame)。每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。
1、局部变量表
存储方法里的局部变量,基础类型和引用类型。虚拟机通过索引定位的方式使用局部变量表。一个对象的实例,局部变量表的第0位索引存储的就是这个实例的引用,也就是在实例方法中的可以调用的this。局部变量表的solt是可以共用的,因为不用的局部变量的范围不一定是整个实例。局部变量表中的变量由于没有经历准备过程,因此不会被赋予默认的初始值。
2、操作数栈
JVM被称为基于栈的虚拟机,这里的栈值得就是操作数栈。操作数栈是代码执行时存放操作数的栈,例如加法操作,先将两个参数从栈顶取出,计算得到结果以后,再将结果压入栈。操作数栈和局部变量表会有一部分重叠。
3、动态连接
栈帧持有一个指向方法区常量池中所属方法的引用。这个引用是为了支持动态连接,动态连接是指符号引用在运行时转化为直接引用。也就是在之前引用A类,是以全类名的符号引用,比如 com.zhoutao123.example.model.A 会被转换为直接引用,引用类型有全类名被修改内存地址的引用。
4、方法返回地址
方法的退出有两种方式,正常执行结束退出和异常退出。异常退出一般根据异常处理表来确定返回地址,栈帧中不会存储这一部分信息。方法的退出实际上就是将栈帧从栈里弹出,恢复上一层栈帧的本地变量表和操作数栈,并且将返回值压入上一栈帧的操作数栈。