局部变量表(Local Variable Table)
局部变量表是一组变量值存储空间,用于存储方法参数和方法内的局部变量。在Java程序编译为Class字节码文件时,就在方法的Code属性(字节码文件)的max_locals数据项中定义了该方法所需要分配的局部变量表的最大容量。
食堂打饭窗口就好比一个局部变量表,食堂创建的时候窗口就已经被规定有几个窗口(这里篡改字节码文件就不多说了。。)
局部变量表中的容量以变量槽(Variable Slot)为最小单位,简称Slot。虚拟机中规范并没有明确指明一个Slot所占应用的内存大小,只是很有向导性的说到每个Slot都应该能存放一个boolean、byte、char、short、int、float、reference或returnAddress类型的数据,这8种数据类型,都可以使用32位或更小的物理内存来存放,也就是占一个食堂窗口。对于64位的数据类型,java中明确规定只有 long和double 两种(reference有可能是32位也有可能是64位),在局部变量表中,把double和long分割存储,占两个Slot,也就是占两个食堂窗口。
代码验证
public class StackTest {
public void localVariableTest(String str){
int i = 0;
}
}
通过 javap -verbose StackTest.class 查看字节码文件信息
可以观察到,在字节码文件方法的Code属性下,locals = 3,说明该方法在编译期间就已经确定了局部变量表最大容量为3个Slot,分别为方法参数,局部变量以及隐式当前调用对象this(注:如果把方法改为static,不会存在this)
public void localVariableTest(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=1, locals=3, args_size=2
0: iconst_0
1: istore_2
2: return
LineNumberTable:
line 6: 0
line 7: 2
LocalVariableTable:
Start Length Slot Name Signature
0 3 0 this Lcom/zhoubin/test/StackTest;
0 3 1 str Ljava/lang/String;
2 1 2 i I
具体字段表示含义
下面我们定一个64位的数据类型
public void localVariableTest(String str){
long l = 10;
int i = 0;
}
通过 javap -verbose StackTest.class 查看字节码文件信息
可以发现,定义的long型局部变量l占用的Slot为2,变量i占用的Slot为4,说明变量l占用了 2、3 两个Slot
public void localVariableTest(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=2, locals=5, args_size=2
0: ldc2_w #2 // long 10l
3: lstore_2
4: iconst_0
5: istore 4
7: return
LineNumberTable:
line 6: 0
line 7: 4
line 8: 7
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 this Lcom/zhoubin/test/StackTest;
0 8 1 str Ljava/lang/String;
4 4 2 l J
7 1 4 i I
持续更新中…如上文有理解有误的地方,欢迎大家指正。
本文学习自周志明老师的深入理解Java虚拟机以及尚硅谷康师傅的jvm视频课程。