JVM学习笔记——栈(Stacks)

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

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

  • 以深度递归为例
	@Test
    public void test_stack_over_flow() throws StackOverflowError {
        StackOverFlow stackOverFlow = new StackOverFlow();
        stackOverFlow.test();
    }
    
    class StackOverFlow {
        int stackLength = 0;

        void test() {
            stackLength++;
            test();
        }
    }

输出结果

java.lang.StackOverflowError
at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)
at com.xxx.xx.xxx.service.xxxServiceTest$StackOverFlow.test(xxxServiceTest.java:2256)

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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值