本文根據(jù)《深入理解java虛擬機(jī)》第8章部分內(nèi)容整理
?
根據(jù)一個代碼實例來介紹虛擬機(jī)中解釋器的執(zhí)行過程,代碼如下所示:
?
public int calculate(){ int a = 100; int b = 200; int c = 300; return (a + b) * c; }
由上面的代碼可以看出,該方法的邏輯很簡單,就是進(jìn)行簡單的四則運(yùn)算加減乘除,我們編譯代碼后使用javap -verbose命令查看字節(jié)碼指令,具體字節(jié)碼代碼如下所示:?
?
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 }
?根據(jù)字節(jié)碼可以看出,這段代碼需要深度為2的操作數(shù)棧(Stack=2)和4個Slot的局部變量空間(Locals=4)。下面,使用7張圖片來描述上面的字節(jié)碼代碼執(zhí)行過程中的代碼、操作數(shù)棧和局部變量表的變化情況。
?
上圖展示了執(zhí)行偏移地址為0的指令的情況,bipush指令的作用是將單字節(jié)的整型常量值(-128~127)推入操作數(shù)棧頂,后跟一個參數(shù),指明推送的常量值,這里是100。
?
上圖則是執(zhí)行偏移地址為1的指令,istore_1指令的作用是將操作數(shù)棧頂?shù)恼椭党鰲2⒋娣诺降?個局部變量Slot中。后面四條指令(3、6、7、10)都是做同樣的事情,也就是在對應(yīng)代碼中把變量a、b、c賦值為100、200、300。后面四條指令的圖就不重復(fù)畫了。
上面展示了執(zhí)行偏移地址為11的指令,iload_1指令的作用是將局部變量第1個Slot中的整型值復(fù)制到操作數(shù)棧頂。
上圖為執(zhí)行偏移地址12的指令,iload_2指令的執(zhí)行過程與iload_1類似,把第2個Slot的整型值入棧。
上圖展示了執(zhí)行偏移地址為13的指令情況,iadd指令的作用是將操作數(shù)棧中前兩個棧頂元素出棧,做整型加法,然后把結(jié)果重新入棧。在iadd指令執(zhí)行完畢后,棧中原有的100和200出棧,它們相加后的和300重新入棧。
上圖為執(zhí)行偏移地址為14的指令的情況,iload_3指令把存放在第3個局部變量Slot中的300入棧到操作數(shù)棧中。這時操作數(shù)棧為兩個整數(shù)300,。
下一條偏移地址為15的指令imul是將操作數(shù)棧中前兩個棧頂元素出棧,做整型乘法,然后把結(jié)果重新入棧,這里和iadd指令執(zhí)行過程完全類似,所以就不重復(fù)畫圖了。
上圖是最后一條指令也就是偏移地址為16的指令的執(zhí)行過程,ireturn指令是方法返回指令之一,它將結(jié)束方法執(zhí)行并將操作數(shù)棧頂?shù)恼椭捣祷亟o此方法的調(diào)用者。到此為止,該方法執(zhí)行結(jié)束。
?
注:上面的執(zhí)行過程只是一種概念模型,虛擬機(jī)最終會對執(zhí)行過程做出一些優(yōu)化來提高性能,實際的運(yùn)作過程不一定完全符合概念模型的描述。不過從這段程序的執(zhí)行過程也可以看出棧結(jié)構(gòu)指令集的一般運(yùn)行過程,整個運(yùn)算過程的中間變量都是以操作數(shù)棧的出棧和入棧為信息交換途徑。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
