简识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)

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

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

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

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

相关推荐
用户0942485680312 小时前
第18章:ConcurrentHashMap与并发容器实战
java·jvm
一条破秋裤16 小时前
Linux 线程分离与主动取消:pthread_detach、pthread_cancel
java·linux·jvm
bksczm19 小时前
零基础面试题1
jvm·数据结构·算法
今天的砖头有点烫手啊20 小时前
GC 算法与垃圾收集器演进:从 Serial 到 ZGC
java·jvm
johnny23321 小时前
JVM生态下Web开发框架:SparkJava、Javalin、Micronaut、SparkKotlin
jvm
晨小安1 天前
ThreadLocal及其内存泄漏问题深度解析
java·jvm·tomcat·哈希表
jingli92 天前
一个测试用例把连接池卡死 30 秒:SQLite 连接池 max_size=1 下的重入自锁复盘
jvm·sqlite·测试用例
imDwAaY2 天前
Java中垃圾回收器 G1 和 CMS 有什么区别?
jvm·后端
xiaoqiMikko2 天前
JVM 线上排查实战(五):升 JDK 17 后进程起不来,十几个老 GC 参数挨个实测(完结)
java·jvm
Flynt2 天前
Java 27 悄悄改了 3 个默认值,我在 1 核小机器上逐个验证了一遍
java·jvm·性能优化