JVM——栈
![](https://img2020.cnblogs.com/blog/2214033/202101/2214033-20210118205757613-1398791769.png)
- 栈管运行,堆管存储
- Java栈在线程创建时创建,它的生命周期跟随线程的生命周期,线程结束占内存也就释放
- 线程私有,不存在垃圾回收机制
- 8种基本类型的变量+对象的引用类型+实例方法都是在函数的栈内存中分配的
- 栈帧(方法压入栈之后叫栈帧)中主要存储3类数据:
本地变量:输入参数和输出参数以及方法内变量
栈操作:记录出栈、入栈操作
栈帧数据:包括类文件、方法等
- 栈运行原理:
栈中数据都是以栈帧的格式存在的,栈帧是一个内存区块,是一个数据集,是一个有关方法和运行期间数据的数据集。
当一个方法A被调用时就产生一个栈帧F1,并被压入栈中,A方法又调用B方法,于是产生栈帧F2也被压入栈中,B方法又调用了C方法,于是产生栈帧F3也被压入栈中……
执行完毕后,先弹出F3栈帧,再弹出F2栈帧,再弹出F1栈帧……
遵循“先进后出”/“后进先出”原则。
每个方法执行时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息,每一个方法从调用直至执行完毕的过程,就对应一个栈帧在虚拟机中入栈到出栈的过程。栈的大小和具体的JVM的实现有关,通常在256K~756K之间。
![](https://img2020.cnblogs.com/blog/2214033/202101/2214033-20210127111728511-285574070.png)
图示中在一个栈中有两个栈帧:栈帧2是最先被调用的方法,先入栈;然后方法2又调用了方法1,栈帧1处于栈顶的位置。执行完毕后,依次弹出栈帧1和栈帧2,线程释放,栈释放。
每执行一个方法就会产生一个栈帧,保存到栈的顶部,顶部栈就是当前方法,方法执行完毕之后就会自动将该栈帧出栈。
public class Test {
public static void m(){
m();
}
public static void main(String[] args){
System.out.println("111");
//Exception in thread "main" java.lang.StackOverflowError
m();
System.out.println("222");
}
}
/*
* output:
* 111
* Exception in thread "main" java.lang.StackOverflowError
*/