目录
参考文章
JVM中的栈帧结构_reachwang的博客-CSDN博客_jvm栈帧结构
JVM基础之栈、栈帧_JustryDeng-CSDN博客_jvm栈帧
概念
栈(栈内存):
作用:主管程序的运行
生命周期:和线程同步,线程结束(main是主线程)栈内存也讲究释放了
垃圾回收:对于栈来说,不存在垃圾回收问题,一旦线程结束,栈也为空了
存放的内容:八大基本类型+对象引用+实例的方法
运行原理与栈帧组成
看下面这个实例
public class Student {
private int a;
private String name="elephant";
void t(){
b();
}
void b(){
t();
}
public static void main(String[] args) {
new Student().t();
}
}
当函数开始执行的时候,会先将main方法压入栈中
然后不断地递归调用,方法开始代表将方法压入栈中,方法结束代表出栈,此处因为是递归调用,所以导致栈溢出,出现StackOverflowEroor错误
栈帧的基本结构
其中在栈中的每一个数据(如main、t())都是一个栈帧,都可以被细分
每一个栈帧都包含
1.局部变量表
2.操作数栈
3.返回地址
4.动态链接(指向运行时常量池的引用)
1.局部变量表(存储八大数据类型和对象实例的引用)
是一组存变量值的空间,用于存放方法参数和内部定义的局部变量(对象实例引用就是调用在一个类里面调用另一个类?)
以变量槽(solt)为基本单位,一个变量槽只允许存放四个字节(32位)的长度变量,超过则会开辟两个连续的solt
其中八大数据类型除了long和double是两个solt,其他都是一个solt
对象实例引用可能是一个solt,也可能是两个slot
2.操作数栈
当在方法刚开始执行时,这个栈是空的,当方法执行的过程中,例如做算术运算等操作是在这个栈中进行的,调用其他方法的时候也是通过这个栈来进行的
类似于把这个方法看成mian方法,然后操作数栈就相当于是java栈内存
3.方法返回地址
当这个栈帧(方法)开始执行后,只有两种方式可以退出
正常完成出口:方法正常完成,返回值传递给上层的方法调用者
正常退出时调用PC计数器的值可以作为返回地址,代表弹出java栈内存,找到这个栈帧下面的栈帧
异常完成出口:方法在执行过程中遇到异常,这个异常没有在方法体内得到处理(比如try,catch,抛异常等操作)导致方法退出
返回地址要通过异常处理表来决定
4.动态链接(指向运行时常量池的引用)
简单理解就是当执行到某个位置的时候,某个置零可能需要常量池的缠住,动态链接就代表这个要引用参数的地址,然后根据这个地址,就可以在方法区的常量池中找到对应地址的常量数据