简识JVM栈帧中的局部变量表

前记:在JVM(Java虚拟机)中,栈帧(Stack Frame)是方法执行时的数据结构,用于存储局部变量、操作数栈、方法返回地址等信息。

栈帧(Stack Frame)是JVM方法执行时所使用的数据结构,而局部变量表(Local Variables Table)则是栈帧中的一个重要组成部分。

以下是对局部变量表的详细解析:

局部变量表的内容与结构类型

局部变量表用于存储方法参数和局部变量,这些数据类型包括各类基本数据类型 (byte、short、int、boolean、float、char、long、double)、对象引用 (reference),以及returnAddress类型。在Java源代码被编译成字节码文件时,局部变量表的最大容量就已经确定。

局部变量表是一个以索引为单位的表格结构,每个变量占据一个或多个索引位置(Slot)。这些Slot用于在方法执行期间存储变量的值。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小(指变量槽的数量不变),但虚拟机真正使用多大的内存空间(譬如1个变量槽占用32个bit、64个bit或者更多)来实现一个变量槽,这是由具体的虚拟机实现自行决定的。

索引结构

局部变量表的索引是从0开始的连续整数。索引0通常用于存储当前方法的this引用(在非静态方法中)。其余的参数和局部变量则按照它们在方法中出现的顺序被依次存储在后续的索引位置上。

对于占用64位的数据类型(如long和double),它们会占用两个连续的索引位置(Slot)。而32位以内的类型(包括引用类型和returnAddress类型)则只占用一个索引位置。

举例说明

以下是一个Java方法的例子,以及该方法局部变量表的详细解析:

java 复制代码
public void exampleMethod(int a, double b) {
    int c = a + 1;
    double d = b + 2.0;
}

在这个例子中,exampleMethod方法有两个参数:a(int类型)和b(double类型),以及两个局部变量:c(int类型)和d(double类型)。

局部变量表的存储情况如下:

  • 索引0:存储a(int类型,占用1个Slot)
  • 索引1和2:存储b(double类型,占用2个Slot)
  • 索引3:存储c(int类型,由于b占用了两个Slot,所以c从索引3开始)
  • 索引4和5:存储d(double类型,占用2个Slot)

需要注意的是,局部变量表中的变量只在当前方法调用中有效。当方法调用结束后,随着方法栈帧的销毁,局部变量表也会随之销毁。

此外,局部变量表中的槽位是可以重用的。如果一个局部变量出了其作用域,那么在其作用域之后声明的新局部变量就很有可能会复用过期局部变量的槽位,从而达到节省资源的目的。

综上所述,栈帧的局部变量表是一个重要的数据结构,它用于在方法执行期间存储局部变量和参数的值。通过索引结构,我们可以方便地访问和操作这些变量。

(望各位潘安、各位子健不吝赐教!多多指正!🙏)

相关推荐
wear工程师1 天前
Java 类初始化到底何时触发?别把加载、连接和 static 执行混在一起
java·jvm
程序员雷欧1 天前
线上频繁触发各种 GC 的原因排查与处理指南
java·jvm·算法
wuminyu2 天前
JVM利用io_uring优化堆外内存性能原理剖析
java·linux·c语言·jvm·c++
147API3 天前
Python批量生成蒸馏数据,并发、重试、幂等和断点续跑
开发语言·jvm·python
wuminyu3 天前
JDK21解决虚拟线程IO阻塞原理剖析
java·linux·c语言·jvm·c++
sunywz3 天前
【JVM】(8)JVM调优实战及常量池详解
jvm
wuminyu4 天前
虚拟线程底层ForkJoinPool的工作窃取算法机制
java·linux·c语言·jvm·c++
leisoo80974 天前
股票数据本地化存储实战:JSON、数据库与列式存储的方案对比
jvm·数据库·json
SamChan904 天前
PDF翻译中的并发控制:用Semaphore防止API限流与资源耗尽
java·jvm·pdf
snow@li4 天前
Java:跨平台原理与JDK、JRE、JVM全景深度解析
java·开发语言·jvm