java class局部变量表
程序员文章站
2024-02-08 14:33:52
...
每个栈帧内部都包含一组称为局部变量表的变量列表,局部变量表的大小在编译期音就已经确定了,对应class文件中方法Code属性的max_locals字段,Java虚拟机会根据max_locals字段来分配方法执行过程中需要分配的最大局部变量表的容量
例一
public class MyJvmTest {
public void foo(int d ,String name){
String tmp ="A";
}
}
class文件
javap -c -v -l MyJvmTest.class
public void foo(int, java.lang.String);
descriptor: (ILjava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=1, locals=4, args_size=3
0: ldc #2 // String A
2: astore_3
3: return
LineNumberTable:
line 13: 0
line 14: 3
LocalVariableTable:
Start Length Slot Name Signature
0 4 0 this Lcom/ghgcn/jvm/chapter02/MyJvmTest;
0 4 1 d I
0 4 2 name Ljava/lang/String;
3 1 3 tmp Ljava/lang/String;
}
locals= 4
第0个局部变量this Lcom/ghgcn/jvm/chapter02/MyJvmTest; 这个实例方法的对象的引用,静态方法没有这个this变量
第1个变量 d I int 类型
第2个变量 name Ljava/lang/String; Stringh引用类型
第3个变量 tmp Ljava/lang/String;
例二
public class MyJvmTest {
public static void foo(){
//locals=0
if(true){
//locals=1
String a ="a";
}
//locals=0
if(true){
//locals =1
String b = "b";
}
//locals =0
}
}
class
public static void foo();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=0
0: ldc #2 // String a
2: astore_0
3: ldc #3 // String b
5: astore_0
6: return
LineNumberTable:
line 30: 0
line 33: 3
line 36: 6
LocalVariableTable:
Start Length Slot Name Signature
}
a和b共用同一个slot等一0的局部变量表位置,当double 和long类型时,这些变量会占用2个局部变量表的slot
操作数
public class MyJvmTest2 {
public void foo(){
bar(1,2,3);
}
private void bar(int a, int b, int c) {
}
}
public void foo();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=4, locals=1, args_size=1
0: aload_0
1: iconst_1
2: iconst_2
3: iconst_3
4: invokespecial #2 // Method bar:(III)V
7: return
LineNumberTable:
line 14: 0
line 16: 7
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 this Lcom/ghgcn/jvm/chapter02/MyJvmTest2;
}
```
stack表示4因为调用bar方法会将this,1,2,3这2个变量压栈,栈的深度为4,调用完后全部出栈.
java
```java
public class MyJvmTest3 {
public void foo(){
bar(1,2,3);
bar(1);
}
private void bar(int a) {
}
private void bar(int a, int b, int c) {
}
}
class
public void foo();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=4, locals=1, args_size=1
0: aload_0
1: iconst_1
2: iconst_2
3: iconst_3
4: invokespecial #2 // Method bar:(III)V
7: aload_0
8: iconst_1
9: invokespecial #3 // Method bar:(I)V
12: return
LineNumberTable:
line 14: 0
line 15: 7
line 17: 12
LocalVariableTable:
Start Length Slot Name Signature
0 13 0 this Lcom/ghgcn/jvm/chapter02/MyJvmTest3;
}
java
public class MyJvmTest3 {
public void foo(){
bar(1,2,3);
bar(1);
bar(1,2,3,4,5);
}
private void bar(int a, int b, int c, int d, int e) {
}
private void bar(int a) {
}
private void bar(int a, int b, int c) {
}
}
class文件
public void foo();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=6, locals=1, args_size=1
0: aload_0
1: iconst_1
2: iconst_2
3: iconst_3
4: invokespecial #2 // Method bar:(III)V
7: aload_0
8: iconst_1
9: invokespecial #3 // Method bar:(I)V
12: aload_0
13: iconst_1
14: iconst_2
15: iconst_3
16: iconst_4
17: iconst_5
18: invokespecial #4 // Method bar:(IIIII)V
21: return
LineNumberTable:
line 14: 0
line 15: 7
line 16: 12
line 18: 21
LocalVariableTable:
Start Length Slot Name Signature
0 22 0 this Lcom/ghgcn/jvm/chapter02/MyJvmTest3;
}
stack=6,
遇到入栈的字节码指令,stack+=1或者stack+=2,根据不同的类型的指令类型,遇到出栈的字节码指令,stack则相应的减少,这个过程中stack的的最大值就是max_stack,也就是javap输出中的stack值
推荐阅读