虛擬機(jī)棧
Java虛擬機(jī)棧(Java Virtual Machine Stack),早期也叫Java棧桑李。每個線程在創(chuàng)建時都會創(chuàng)建一個虛擬機(jī)棧,其內(nèi)部保存一個個的棧幀(Stack Frame),對應(yīng)著一次次的Java方法調(diào)用蜒犯,所以有時也會稱作為虛擬機(jī)幀棧组橄。
棧幀的內(nèi)部結(jié)構(gòu)
1、局部變量表(Local Variables)
????局部變量表是一組變量值存儲空間罚随,用于存放方法參數(shù)和方法內(nèi)部定義的局部變量玉工。在Java程序編譯為Class文件時,就在方法表的Code屬性的max_locals數(shù)據(jù)項中確定了該方法需要分配的最大局部變量表的容量淘菩。
?????局部變量表遵班,最基本的存儲單元是Slot(變量槽)局部變量表中存放編譯期可知的各種基本數(shù)據(jù)類型(8種),引用類型(reference)潮改,returnAddress類型的變量狭郑。
????在局部變量表里,32位以內(nèi)的類型只占用一個slot(包括returnAddress類型)进陡,64位的類型(1ong和double)占用兩個slot愿阐。
????局部變量表的第0個局部變量一定用來存儲該實例方法所在的對象的引用,即java中的this關(guān)鍵字
java文件
public class LocalVerial {
public double add2And3(int a,int b){
int d=20;
double c=1.79769e+308;
return a+b+c+d;
}
}
java文件對應(yīng)的字節(jié)碼文件內(nèi)容
public double add2And3(int, int);
descriptor: (II)D
flags: ACC_PUBLIC
Code:
stack=4, locals=6, args_size=3
0: bipush 20
2: istore_3
3: ldc2_w #2 // double 1.79769E308d
6: dstore 4
8: iload_1
9: iload_2
10: iadd
11: i2d
12: dload 4
14: dadd
15: iload_3
16: i2d
17: dadd
18: dreturn
LineNumberTable:
line 5: 0
line 6: 3
line 7: 8
LocalVariableTable:
Start Length Slot Name Signature
0 19 0 this Lcom/interview/jvm/classfifle/LocalVerial;
0 19 1 a I //參數(shù)a
0 19 2 b I //參數(shù)b
3 16 3 d I //局部變量d
8 11 4 c D //局部變量c
源代碼中形參和變量的聲明順序為a趾疚、b缨历、d、c糙麦,所以在本地變量表對應(yīng)的變量槽(slot)從1到4也為a辛孵、b、d赡磅、c的順序魄缚。
2、操作數(shù)棧(operand Stack)
用來存放方法運行期間焚廊,各個指令操作的數(shù)據(jù)冶匹。
public class MethodOperatorStack {
public int add(int a,int b){
int c=5;
return a+b+c;
}
}
Code:
stack=2, locals=4, args_size=3
0: iconst_5
1: istore_3
2: iload_1
3: iload_2
4: iadd
5: iload_3
6: iadd
7: ireturn
LineNumberTable:
line 5: 0
line 6: 2
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 this Lcom/interview/jvm/classfifle/MethodOperatorStack;
0 8 1 a I
0 8 2 b I
2 6 3 c I
0:iconst_5
iconst指令含義:將int類型常量入棧到操作棧中
iconst_5含義:將常量5壓入操作棧
1:istore_3:
istore:將int類型數(shù)據(jù)保存到本地變量表中
istore_3:即將int類型數(shù)據(jù)保存到本地變量表中索引為3的變量槽c中
2:iload_1
iload:從局部變量表中加載一個int類型值到操作數(shù)棧
iload_1:將局部變量表中Slot為1的值加載到操作數(shù)棧,即將參數(shù)a的值加載到操作數(shù)棧
3:iload_2
iload:從局部變量表中加載一個int類型值到操作數(shù)棧
iload_2:將局部變量表中Slot為1的值加載到操作數(shù)棧咆瘟,即將參數(shù)b的值加載到操作數(shù)棧
4:iadd
iadd:int類型數(shù)據(jù)相加,指令執(zhí)行時嚼隘,加載過的a和b的從操作數(shù)棧中出棧,將這個兩個數(shù)數(shù)值相加得到int類型數(shù)據(jù)結(jié)果后入棧到操作數(shù)棧中
5:iload_3
iload:從局部變量表中加載一個int類型值到操作數(shù)棧
iload_3:將局部變量表中Slot為3的值加載到操作數(shù)棧袒餐,即將參數(shù)c的值加載到操作數(shù)
6: iadd
iadd:int類型數(shù)據(jù)相加,指令執(zhí)行時飞蛹,此時操作棧里面a+b的結(jié)果和c的值從操作數(shù)棧中出棧,將這個兩個數(shù)數(shù)值相加得到int類型數(shù)據(jù)結(jié)果后入棧到操作數(shù)棧中
7:ireturn
ireturn:從方法中返回一個int類型數(shù)據(jù)