JVM运行时数据区-虚拟机栈
Java虚拟机栈(Java Virtual Machine Stack):
基本概述:
跨平台设计,Java指令根据栈来设计的,不同平台CPU架构不同,所以不能设计为基于寄存器的
线程私有的,每个线程创建时都会创建一个虚拟机栈,其内部保存一个个栈帧(Stack Frame),一个栈帧对应一个Java方法。
内存中的栈与堆的区别:
堆:存储数据区域
栈:运行时数据区域
栈与堆数据存放区别:
堆:主体数据存放堆区(对象存放堆中)
栈:局部变量存放在栈空间中(基本数据类型),如果是引用数据类型(在栈空间存放数据对象的引用)。
栈的生命周期:
栈的生命周期和线程一致。
栈的作用:
栈是Java程序运行时的一块区域,用于保存局部变量,部分结果并参与方法的调用和返回。
局部变量:
基本类型变量:8种基本数据类型变量
引用类型变量:(类、数组、接口)在栈中存放,对象引用地址。
栈的优点:
栈是一种有效的分配存储方式,访问速度仅次于程序计数器(PC寄存器)。
Java栈操作:
1) 每个方法执行(入栈)
2) 方法执行结束(出栈)
3) 遵循先进后出原则
栈不存在GC垃圾回收问题(因为都是入栈/出栈操作)
栈会出现内存溢出问题(可通过设置栈内存大小 -Xss)
栈中异常问题:
Java虚拟机规范允许Java栈大小是动态扩展或固定大小的。
固定大小:如果线程请求分配的栈容量超过Java虚拟机栈允许的最大容量,Java虚拟机栈会抛出StackOverflowError(栈溢出)异常。
动态扩展:如果扩展时无法申请到足够内存,或在创建新的线程时没有足够的内存去创建对应的虚拟机栈,会抛出OutOfMemoryError(内存溢出)异常。
栈的存储单位:
栈中的数据是以栈帧(Stack Frame)的格式存放。
每个线程都有一个栈,当前线程正在执行的每个方法都对应一个栈帧(方法执行->入站,执行结束->出栈)
栈帧是一个内存区块/数据集,维护方法执行过程中各种数据信息。
在一条活动的线程中,只会有一个活动栈帧,只有当前正在执行方法的栈帧(栈顶栈帧)是有效的,这个栈帧被称为“当前栈帧”(Current Frame),与当前栈帧相对应的方法是“当前方法”(Current Method),定义这个方法的类是“当前类”(Current Class)。
执行引擎运行的所有字节码指令只针对当前栈帧进行操作。
如果在方法中调用了其他方法,对应的新的栈帧会被创建出来,放在栈的顶端,成为新的当前栈帧。方法返回时,当前栈帧会传回此方法的执行结果给前一个栈帧,然后虚拟机会丢弃当前栈帧,使前一个栈帧重新成为当前栈帧。
不同线程中所包含的栈帧不允许存在互相引用的。
Java中方法有两种返回方式:1) Return 2) 抛出异常(未try catch处理异常)不管哪种方式返回都会导致栈帧被弹出。