JVM复习之虚拟机栈之栈帧之局部变量表、操作数栈

虚拟机栈

出现背景

由于跨平台的设计,Java指令都是根据栈来设计,不同CPU架构不同,所以不能设计为基于寄存器的。

  • 优点:指令集小,编译器容易实现
  • 缺点:性能下降,实现同样操作需要更多指令。

为什么Java开发人员一提到Java内存结构,就会将内存区理解为堆和栈?

栈是运行的单位。堆是存储的单位

Java虚拟机栈是什么?

Java Virtual Machine Stack,每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈针,对应着一次一次的方法调用。

生命周期

和线程生命周期一起。

作用
  • 管理程序运行,保存方法的局部变量(基本数据类型和对应引用地址)、部分结果、并参与方法的调用和返回。

栈的特点

  • 快速分配存储的方式,速度仅次于程序计数器。
  • 每个方法执行都伴随进栈和出栈。
  • 不存在垃圾回收问题。

设置栈内存大小

我们知道,在递归执行时,如果没有正确指明返回条件,会抛出StackOverflowError异常。
另外一种情况就是分配的大小超出了栈的空间。

可以通过-Xss来设置线程最大的栈空间。这个值决定了函数调用的最大可达深度。


栈的存储单位

栈中存储什么?

每个线程都有自己的栈,栈中的数据都是以**栈帧(Stack Frame)**格式存在。

  • 栈帧是一块内存,一个数据集。维系方法执行过程中的各种数据信息。

  • JVM对栈的操作只有压栈和出栈,遵循先进后出。

  • 线程的一个时间点上,只有一个活动栈帧,这个栈针叫做当前栈帧,对应的方法叫当前方法,对应的类叫当前类。

栈运行图解

JVM复习之虚拟机栈之栈帧之局部变量表、操作数栈_第1张图片

解释
  • 不同线程中包含的栈帧不允许相互引用。
  • 每个栈帧对应的方法结束返回之际,JVM会丢弃该栈帧,使前一个栈针重新成为当前栈帧。
  • 方法有两种返回形式:一是return指令正常返回;二是抛出异常。

栈的内部结构

JVM复习之虚拟机栈之栈帧之局部变量表、操作数栈_第2张图片

局部变量表
  • 定义数字数组,存储方法参数和定义在方法体内的局部变量。包括基本数据类型、对象引用,以及returnAddress类型。
  • 局部变量表建立在线程的栈上,所以不存在数据安全问题。
  • 其容量大小在编译期确定下来。
局部变量表中Slot的理解
  1. slot是其基本存储单位。
  2. 32位内的类型栈一个slot(如int,不是int的会转换成int),64位类型占两个slot(如double和long)

我们知道静态方法不能使用this,为什么?

因为this这个变量不存在于当前这个静态方法的局部变量表。换句话说,静态方法局部变量表中没有this,非静态方法中存在this。

操作数栈

每个栈针除了局部变量表外,还包含一个先进后出的操作数栈。也叫表达式栈。

  • 操作数栈,在方法执行中,根据字节码指令,往栈中写入数据或提取数据,即入栈/出栈。
  • 如果调用的方法带有返回值,其返回值将会被压入当前栈针操作数栈中,随即更新PC寄存器中下一条需要执行的字节码指令。
  • 用于保存计算过程中的中间结果,同时作为计算过程中的临时的存储空间。
    JVM复习之虚拟机栈之栈帧之局部变量表、操作数栈_第3张图片

你可能感兴趣的:(jvm,jvm,java)