JVM进阶(一) 初识JAVA栈

虚拟机模型图
Java栈是我们最常用的内存区域,线程私有。它主要用来存放基本类型变量、局部变量以及对象的引用。例如:User user = new User(),这里的 user 就是对象对象的引用也可以理解为地址,指引着虚拟机要去哪里找 user 这个对象。它们的基本关系如图:
在这里插入图片描述

由图可知,当我们将一个对象作为方法的参数时,我们在方法中改变对象的值,也会影响到原来的对象的值,因为我们只是改变了图中内存区域的值,它们的指引(地址)还是一样的。同时也可以看出,栈的内存区域是连续的,有大小限制的,如果超出了就会抛出栈溢出的错误 StackOverflowError【属于Error,程序会终止,无法捕获处理】 。
在每个方法执行的时候,都会在栈区域创建一个个的栈帧,用于保存局部变量表、操作数栈、动态链接等信息。每次方法的调用都会对应着一个栈帧,因此可以解释我们在写递归程序的时候会不小心报栈溢出的错误:因为栈是有限的,方法调用太多次就会导致栈帧堆满了栈,所以溢出。

代码演示:

package org.zpli.java8.jvmapi;

/**
 * @Description: TODO
 * @Copyright: 
 * @author: 
 * @Date: 2020/3/26 17:18
 */
public class StackOverflowErrorDemo {

    private int stackCount;

    public static void main(String[] args) {
        StackOverflowErrorDemo demo = new StackOverflowErrorDemo();
        try {
            demo.stackOverflow();
        } catch (Throwable e) {
            System.out.println("stackCount : " + demo.stackCount);
            e.printStackTrace();
        }
    }

    private void stackOverflow() {
        stackCount++;
        stackOverflow();
    }
}

输出结果:

stackCount  20738
java.lang.StackOverflowError
	at org.zpli.java8.jvmapi.StackOverflowErrorDemo.stackOverflow(StackOverflowErrorDemo.java:25)
	at org.zpli.java8.jvmapi.StackOverflowErrorDemo.stackOverflow(StackOverflowErrorDemo.java:25)
	at org.zpli.java8.jvmapi.StackOverflowErrorDemo.stackOverflow(StackOverflowErrorDemo.java:25)
	at org.zpli.java8.jvmapi.StackOverflowErrorDemo.stackOverflow(StackOverflowErrorDemo.java:25)
	at org.zpli.java8.jvmapi.StackOverflowErrorDemo.stackOverflow(StackOverflowErrorDemo.java:25)

每次在方法执行的时候会进行入栈操作,在方法执行完毕以后会进行出栈操作,虚拟机会自动释放掉为该栈所分配的空间。栈结构采用先进后出的操作方式,先入栈的数据总是在栈底,后入栈的数据总是在栈顶,出栈的时候总是从栈顶开始。

总结:

  • 栈是线程私有的
  • 存放基本类型变量,局部变量,对象的引用;
  • 系统自动分配与回收内存,效率较高,快速,存取速度比堆要快;
  • 是一块连续的内存的区域,有大小限制,如果超过了就会栈溢出,并抛出栈溢出的异常StackOverflowError;
  • 方法执行完毕以后 jvm 会自动释放掉为该变量所分配的内存空间;

栈又分为java栈和本地方法栈。顾名思义,本地方法栈自然就是为本地方法提供服务的,java栈是为java服务的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值