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、栈和堆的区别

  1. 从GC、OOM、StackOverflowError的角度。
    栈中不存在GC,当固定大小的栈会发生OOM,动态的会发生StackOverflowError。
    堆中GC、OOM、StackOverflowError都存在
  2. 堆栈的执行效率
    栈的效率高于堆
  3. 内存大小,数据结构角度
    一般堆的空间比栈的大
    栈是一种FIFO先进后出的模型。堆中结构复杂,可以有链表、数组等
  4. 功能角度
    栈是运行时的单位,栈解决程序的运行问题,即程序如何之星,或者说如何处理数据。
    堆是存储的单位,堆解决的是数据存储的问题,即数据怎么放、放在哪。

1.3、常见异常与设置栈的大小

Java虚拟机规范允许Java栈的大小是动态的或者是固定不变的

  1. 如果采用固定大小的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+。

  1. 如果Java虚拟机栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者是在创建新的线程时就没有足够的内存去创建对应的虚拟机栈,那Java虚拟机将会抛出一个OutOfMemoryError异常

2、栈的存储单位(栈帧)

一个方法的执行对应一个栈帧(Stack Frame)入栈,方法结束,对应栈帧出栈。

正常返回,return;抛出异常(未处理异常),这两种情况都会导致栈帧被弹出。

栈帧:

  1. 局部变量表(Local Variables)
  2. 操作数栈(Operand stack),表达式栈
  3. 动态链接(Dynamic Linking):指向运行时常量池的方法引用
  4. 方法返回地址(Return Address):方法正常退出或者异常退出的定义
  5. 一些附加信息

3、局部变量表

3.1、概念

3.2、Slot(变量槽)

3.3、静态变量与局部变量的对比

4、操作数栈

5、代码追踪

6、栈顶缓存技术

7、动态链接

8、方法的调用:解析与分派

9、方法返回地址

10、一些附加信息

11、栈的相关面试题

以上是关于JVM05_虚拟机栈的主要内容,如果未能解决你的问题,请参考以下文章

JVM专题-虚拟机栈

JVM_03 运行时数据区1-[程序寄存器+虚拟机栈+本地方法栈]

JVM_05 运行时数据区2-堆

jvm虚拟机栈的作用

Day326&327.虚拟机栈 -JVM

jvm内存区域之虚拟机栈