本文根據《深入理解java虛擬機》第8章部分內容整理
?
根據一個代碼實例來介紹虛擬機中解釋器的執行過程,代碼如下所示:
?
public int calculate(){
int a = 100;
int b = 200;
int c = 300;
return (a + b) * c;
}
由上面的代碼可以看出,該方法的邏輯很簡單,就是進行簡單的四則運算加減乘除,我們編譯代碼后使用javap -verbose命令查看字節碼指令,具體字節碼代碼如下所示:?
?
public int calculate();
Code:
Stack=2, Locals=4, Args_size=1
0: bipush 100
2: istore_1
3: sipush 200
6: istore_2
7: sipush 300
10: istore_3
11: iload_1
12: iload_2
13: iadd
14: iload_3
15: imul
16: ireturn
LineNumberTable:
line 3: 0
line 4: 3
line 5: 7
line 6: 11
}
?根據字節碼可以看出,這段代碼需要深度為2的操作數棧(Stack=2)和4個Slot的局部變量空間(Locals=4)。下面,使用7張圖片來描述上面的字節碼代碼執行過程中的代碼、操作數棧和局部變量表的變化情況。
?
上圖展示了執行偏移地址為0的指令的情況,bipush指令的作用是將單字節的整型常量值(-128~127)推入操作數棧頂,后跟一個參數,指明推送的常量值,這里是100。
?
上圖則是執行偏移地址為1的指令,istore_1指令的作用是將操作數棧頂的整型值出棧并存放到第1個局部變量Slot中。后面四條指令(3、6、7、10)都是做同樣的事情,也就是在對應代碼中把變量a、b、c賦值為100、200、300。后面四條指令的圖就不重復畫了。
上面展示了執行偏移地址為11的指令,iload_1指令的作用是將局部變量第1個Slot中的整型值復制到操作數棧頂。
上圖為執行偏移地址12的指令,iload_2指令的執行過程與iload_1類似,把第2個Slot的整型值入棧。
上圖展示了執行偏移地址為13的指令情況,iadd指令的作用是將操作數棧中前兩個棧頂元素出棧,做整型加法,然后把結果重新入棧。在iadd指令執行完畢后,棧中原有的100和200出棧,它們相加后的和300重新入棧。
上圖為執行偏移地址為14的指令的情況,iload_3指令把存放在第3個局部變量Slot中的300入棧到操作數棧中。這時操作數棧為兩個整數300,。
下一條偏移地址為15的指令imul是將操作數棧中前兩個棧頂元素出棧,做整型乘法,然后把結果重新入棧,這里和iadd指令執行過程完全類似,所以就不重復畫圖了。
上圖是最后一條指令也就是偏移地址為16的指令的執行過程,ireturn指令是方法返回指令之一,它將結束方法執行并將操作數棧頂的整型值返回給此方法的調用者。到此為止,該方法執行結束。
?
注:上面的執行過程只是一種概念模型,虛擬機最終會對執行過程做出一些優化來提高性能,實際的運作過程不一定完全符合概念模型的描述。不過從這段程序的執行過程也可以看出棧結構指令集的一般運行過程,整個運算過程的中間變量都是以操作數棧的出棧和入棧為信息交換途徑。
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

