每個棧幀內部都包含一組稱爲局部變量表的變量列表,局部變量表的大小在編譯期音就已經確定了,對應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值