文章目录
Java虚拟机栈
1、内存中的栈和堆
栈:
是运行时的单位,而堆时存储的单位
栈解决程序的运行问题,即程序如何执行,或者如何处理数据,堆解决的数据的存储问题。
2、Java虚拟机栈是什么?
Java虚拟机栈(Java Virtual Machie Stack),早期也叫Java栈。每个线程在创建时都会创建一个虚拟机栈,内部保存一个个的栈帧(Stack Frame),对应的一次次的Java方法调用。
1)作用和特点:
作用:管理Java程序的运行,它保存方法的局部变量,部分结果,并参与方法的调用和返回,对于栈来说不存在垃圾回收问题。
Java栈的特点 :
- 是
线程私有的生命周期和线程一样
- 一个方法的调用对应着一个
栈帧
,每个方法执行,伴随着进栈(入栈,压栈)
,执行结束后的出栈工作
2)Java虚拟机规范允许Java栈的大小是动态的或者是固定不变
- 如果采用
固定大小的Java虚拟机栈
,每一个线程的Java虚拟机栈容量可以在线程创建的时候就独立确定
- 如果线程请求分配的栈容量
超过了Java虚拟机栈允许的最大容量
,Java会抛出一个StackOverflowError异常。
如果Java虚拟机栈可以动态拓展,并在尝试拓展的时候无法获取到足够的内要,或者创建新的线程是没有足够的内要空间空间去创建对应的虚拟机栈,那Java虚拟机就会抛出一个OutOfMenoryError异常。
3)设置栈内存的大小
使用参数 -Xss
选项来设置线程的最大栈空间,栈的大小直接决定函数的最大可达深度。
-Xss265k
3、栈的存储的内容和运行的原理
1)栈中存储什么?
- 每个线程都有自己的栈,栈中的数据都是以栈帧(Stack Frame)的格式存在
- 在这个线程上正在执行的每个方法都各自对应一个栈帧
- 栈帧是一个内存区块,是一个数据集,维系着方法执行过程中的各种数据信息。
2)栈运行的原理
-
栈的操作只有两个:压栈和出栈,遵循“先进后出”原则
-
在一个活动线程中,一个时间点上,只会有一个活动的栈帧,即只有当前正在执行的方法的栈帧(栈顶栈帧)是有效的,这个栈帧被称为
当前栈帧
,于当前栈帧对应的方法就是当前方法
,定义这个类的就是当前类。 -
执行引擎运行开所有字节码指令只针对当前栈帧进行执行
-
如果该方法调用了其他方方法,就会有新的栈帧会被创建处理,放在栈顶端,称为新的当前栈帧。
-
不同线程中所包含的栈帧是不允许存在互相引用的,即不可能在一个栈帧中引用另一个线程的栈帧。
-
如果当前方调用了其他方法,方法返回直接,当前栈帧会传回此方法执行的结果给前一个栈帧,接着,虚拟机就会丢弃当前栈帧,使得前一个栈帧重新成为当前栈帧。
public class JVMStackTest{
public static void main(String[] args){
JVMStackTeststack = new JVMStackTest();
stack.method1
}
public void method1(){
System.out.println("运行方法1");
int result = method2()
}
public int metthod2(){
System.out.println("运行方法2");
method3();
return 0;
}
public void method3(){
System.out.println("运行方法3");
method4();
}
public void method4(){
System.out.println("运行方法4");
}
}
- Java方法又两种返回函数类型,一种是正常的函数返回,使用return指令,另一种是抛出异常,不管使用哪种方式,都是导致栈帧被弹出。
4、栈帧的内部结构
如上图所示:栈帧由局部变量表、方法返回地址、操作栈、动态链接、还有一些附加信息组成。
1) 局部变量表
局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(Reference类型)。
上面所说的对象引用,它不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置。