JVM学习笔记——栈(Stacks)

小鱼儿 2023-06-19 09:32 114阅读 0赞
Java中的栈分为Java虚拟机栈和本地方法栈。
  • Java虚拟机栈是线程私有的,它的生命周期和线程一样。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量、操作数栈、动态链接、方法出口等信息。每一个方法从调用到执行完毕的过程,就意味着一个栈帧在虚拟机栈中入栈到出栈的过程。
  • 本地方法栈和Java虚拟机栈的作用基本是相同的,他们之间的区别不过是Java虚拟机栈为虚拟机执行Java方法(也就是字节码服务),而本地方法栈则为虚拟机使用的Native方法服务。说白了就是本地方法栈自然就是为本地方法提供服务的,Java虚拟机栈是为Java服务的。本地方法栈同样会出现StackOverflowError和OutOfMemoryError。
  • 如果栈请求的深度大于虚拟机允许的深度,则会抛出StackOverflowError。如果虚拟机可以动态扩展,如果扩展到无法申请足够的内存的时候就会抛出OutOfMemoryError。
栈与内存的关系

栈是我们最常用的内存区域。它主要用来存放基本类型变量,局部变量以及对象的引用。例如:User user = new User();这里的user就是对象的引用也可以理解为地址,指引着虚拟机要去哪里找user这个对象。
在这里插入图片描述
由图可知,当我们将一个对象作为方法的参数时,我们在方法中改变对象的值,也会影响到原来的对象的值,因为我们只是改变了图中内存区域的值,他的指引(地址)还是一样的。同时也可以看出,栈的内存区域是连续的,有大小限制的,如果超过了就会抛出栈溢出的异常StackOverflowError。

  • 以深度递归为例

    @Test

    1. public void test_stack_over_flow() throws StackOverflowError {
    2. StackOverFlow stackOverFlow = new StackOverFlow();
    3. stackOverFlow.test();
    4. }
    5. class StackOverFlow {
    6. int stackLength = 0;
    7. void test() {
    8. stackLength++;
    9. test();
    10. }
    11. }

输出结果

  1. java.lang.StackOverflowError
  2. at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
  3. at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
  4. at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
  5. at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
  6. at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
  7. at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
  8. at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
  9. at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
  10. at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)

每次在方法执行完毕的时候,虚拟机会自动释放掉为该栈所分配的空间,在栈中,对应着一个栈帧的出栈。虚拟机会自动分配与回收内存,因此效率比较高。

总结
  • JVM栈是每个线程私有的
  • 存放基本类型变量,局部变量,对象的引用
  • 系统自动分配与回收内存,效率较高,快速,存取速度比堆要快
  • 是一块连续的内存的区域,有大小限制,如果超过了就会栈溢出,并抛出栈溢出的异常StackOverflowError
  • Java会自动释放掉为该变量所分配的内存空间
  • 虚拟机在扩展栈时无法申请到足够的内存,则抛出OOM

发表评论

表情:
评论列表 (有 0 条评论,114人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Stack

    一,概念 > 一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO

    相关 stack

    1.什么是栈? 栈(stack)是一种只能在表的一端进行插入和删除的线性表。是一种一对一的线性关系。因为只能在栈顶进行插入和删除.这种结构特性决定了栈只能的性质:后进先

    相关 JVM--Stack

    栈(Stack) 栈也叫栈内存,主管java程序的运行,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题, 只要线程

    相关 Stack()

    【一】Stack(栈) > 特点:它是一个先进后出的有序列表 >     允许插入和删除的一端为栈顶(top),另一端为栈底(bottom) >     出栈pop,