JVM05_虚拟机栈
Posted root_zhb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM05_虚拟机栈相关的知识,希望对你有一定的参考价值。
虚拟机栈
1、概述
1.1、Java虚拟机栈是什么
Java虚拟机栈(Java Virtual Machine Stack),内部保存一个个栈帧(Stack Frame),对应一次次的Java方法调用。
线程私有的
生命周期和线程一致。
无GC,存在StackOverflowError和OOM
作用:主管Java程序的运行,保存局部变量、部分结果,并参与方法的调用和返回。
1.2、栈和堆的区别
- 从GC、OOM、StackOverflowError的角度。
栈中不存在GC,当固定大小的栈会发生OOM,动态的会发生StackOverflowError。
堆中GC、OOM、StackOverflowError都存在 - 堆栈的执行效率
栈的效率高于堆 - 内存大小,数据结构角度
一般堆的空间比栈的大
栈是一种FIFO先进后出的模型。堆中结构复杂,可以有链表、数组等 - 功能角度
栈是运行时的单位,栈解决程序的运行问题,即程序如何之星,或者说如何处理数据。
堆是存储的单位,堆解决的是数据存储的问题,即数据怎么放、放在哪。
1.3、常见异常与设置栈的大小
Java虚拟机规范允许Java栈的大小是动态的或者是固定不变的
- 如果采用固定大小的Java虚拟机栈,那每一个线程的Java虚拟机栈容量可以在线程创建的时候独立选定。如果线程请求分配的栈容量超过Java虚拟机栈允许的最大容量,Java虚拟机将会抛出一个StackoverflowError异常
public class StackDeppTest {
private static int count=0;
public static void recursion(){
count++;
recursion();
}
public static void main(String[] args) {
try {
recursion();
}catch (Throwable e){
System.out.println("deep of calling=" + count);
e.printStackTrace();
}
}
}
栈的大小直接决定了函数调用的最大可达深度
设置栈的大小:run -> edit Configuration -> Modify options -> java -> add VM options
-Xss256k
可以看到设置256k,调用深度为5000+;设置128k,调用深度为2500+。
- 如果Java虚拟机栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者是在创建新的线程时就没有足够的内存去创建对应的虚拟机栈,那Java虚拟机将会抛出一个OutOfMemoryError异常
2、栈的存储单位(栈帧)
一个方法的执行对应一个栈帧(Stack Frame)入栈,方法结束,对应栈帧出栈。
正常返回,return;抛出异常(未处理异常),这两种情况都会导致栈帧被弹出。
栈帧:
- 局部变量表(Local Variables)
- 操作数栈(Operand stack),表达式栈
- 动态链接(Dynamic Linking):指向运行时常量池的方法引用
- 方法返回地址(Return Address):方法正常退出或者异常退出的定义
- 一些附加信息
3、局部变量表
3.1、概念
3.2、Slot(变量槽)
3.3、静态变量与局部变量的对比
4、操作数栈
5、代码追踪
6、栈顶缓存技术
7、动态链接
8、方法的调用:解析与分派
9、方法返回地址
10、一些附加信息
11、栈的相关面试题
以上是关于JVM05_虚拟机栈的主要内容,如果未能解决你的问题,请参考以下文章