Java虚拟机栈(Java Virtual Machine Stack) ,早期也叫Java栈。每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame),对应着一次次的Java方法调用。 下面会较为仔细地说一下 JVM内存结构之虚拟机栈 。

JVM内存结构之虚拟机栈
JVM内存结构之虚拟机栈

1. JVM虚拟机栈的 生命周期

因为每个线程都有自己的独立虚拟机栈,所以它的生命周期和线程一致。当线程结束生命周期,对应的虚拟机栈也就结束了它的生命周期。

2.JVM虚拟机栈的作用

主管Java程序的运行,它保存方法的局部变量(8种基本数据类型\对象的引用和地址)、部分结果,并参与方法的调用和返回。

  1. 局部变量 VS 成员变量(属性)。
  2. 基本数据类型变量 VS 引用类型变量(类、数组、接口)。

3.JVM虚拟机栈的特点

  1. 栈是一种快速有效的分配存储方式,速度仅仅次于程序计数器。
  2. JVM对虚拟机栈 只有两个操作,每个方法的执行,方法对应的栈帧入栈;方法执行完毕,方法对应的栈帧出栈
  3. 对JVM虚拟机栈来说,可能会存在OOM(内存溢出),但是不会有GC

4.JVM虚拟机中的内容

JVM内存结构之虚拟机栈
JVM内存结构之虚拟机栈
  1. 每个线程都有自己的栈,栈中的数据都是以栈帧(Stack Frame) 的格式存在。
  2. 在这个线程上正在执行的每个方法都各自对应一个栈帧(Stack Frame) 。
  3. 栈帧是一个内存区块,是-一个数据集,维系着方法执行过程中的各种数据信息。

5.JVM栈帧内部结构

  1. 局部变量表(Local variables )。
  2. 操作数栈(operand Stack) ( 或表达式栈)。
  3. 动态链接(Dynamic Linking) ( 或指向运行时常量池的方法引用) 。
  4. 方法返回地址(Return Address) (或方法 正常退出或者异常退出的定义)。
  5. 一些附加信息
JVM内存结构之虚拟机栈
JVM栈帧内部结构

局部变量表

  1. 局部变量表也被称之为局部变量数组或本地变量表。
  2. 定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类基本数据类型、对象引用(reference) ,以及returnAddress类型。
  3. 由于局部变量表是建立在线程的栈上,是线程的私有数据,因此不存在数据安全问题。
  4. 局部变量表所需的容量大小是在编译期确定下来的,并保存在方法的Code属性的maximum local variables数据项中。在方法运行期间是不会改变局部变量表的大小的。

操作数栈

操作数栈,在方法执行过程中,根据字节码指令,往栈中写入数据或提取数据,即入栈(push) /出栈(pop)。 例如:

  1. 某些字节码指令将值压入操作数栈,其余的字节码指令将操作数取出栈。使用它们后再把结果压入栈。
  2. 比如:执行复制、交换、求和等操作
JVM内存结构之虚拟机栈
操作数栈执行iadd操作

动态链接

首先动态链接其实就是指向运行时常量池的方法引用

  1. 每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用。包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接(Dynamic Linking) 。比如: invokedynamic指令。
  2. 在Java源文件被编译到字节码文件中时,所有的变量和方法引用都作为符号引用(Symbolic Reference)保存在class文件的常量池里。比如:描述一个方法调用了另外的其他方法时,就是通过常量池中指向方法的符号引用来表示的,那么功态链接的作用就是为了将这些符号引用转换为调用方法的直接引用。
JVM内存结构之虚拟机栈
动态链接

方法返回地址

方法返回地址存放调用该方法的PC寄存器的值。一个方法的结束有两种方法:

  1. 执行完正常退出
  2. 出现未处理的异常,异常退出。

但是无论是上面样的形式退出,方法退出后都要返回到该方法被调用的地方。调用者的PC寄存器作为返回地址,即调用改方法指令的下一条指令地址。通过异常退出的,需要通过异常表来确定,栈帧中一般不会保存这部分信息。

其他附加信息

栈帧中还允许携带与Java虛拟机实现相关的一 些附加信息。例如,对程序调试提供支持的信息。

6.JVM虚拟机栈异常

Java虚拟机规范中允许虚拟机栈的大小可以是固定不变或者动态拓展的。下面就会有两种情况会导致JVM虚拟机异常或者错误。

  1. 如果JVM虚拟机栈的大小是固定的,线程中每一个方法对应一个栈帧。 如果线程请求分配的栈容量超过Java虚拟机栈允许的设大容量,Aava虚拟机将会抛出一个StackOverflowError异常。
  2. 还有就是在动态的虚拟机栈中, 如果Java虚拟机栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的虚拟机栈那Java虚拟机将会抛出一个outOfMemoryError 异常。

标签云

ajax AOP Bootstrap cdn Chevereto CSS Docker Editormd GC Github Hexo IDEA JavaScript jsDeliver JS樱花特效 JVM Linux Live2D markdown Maven MyBatis MyBatis-plus MySQL Navicat Oracle Pictures QQ Sakura SEO Spring Boot Spring Cloud Spring Cloud Alibaba SpringMVC Thymeleaf Vue Web WebSocket Wechat Social WordPress Yoast SEO 代理 分页 图床 小幸运 通信原理

JVM内存结构之虚拟机栈
JVM内存结构之虚拟机栈