虛擬機器位元組碼執行引擎——執行時棧幀結構
文章目錄
虛擬機器與物理機異同
同:都具有程式碼執行能力
異:物理機的執行引擎是建立在處理器、硬體、指令集和作業系統上面的;而虛擬機器的執行引擎是自己實現的,因此可以自行制定指令集。
棧幀
棧幀儲存了方法的區域性變量表、運算元棧、動態連線、方法返回地址等資訊。每一次方法的呼叫和完成都對應一個棧幀的入棧和出棧。
在編譯程式碼階段,棧幀裡面的區域性變量表需要多大記憶體空間是已經確定了的。
棧幀的結構
一、區域性變量表
區域性變量表
是一組變數值儲存空間,用來存放方法引數和方法內部定義的區域性變數。
區域性變量表容量的最小單元
區域性變量表以變數槽(variable slot)為最小單元。變數槽的大小,java虛擬機器規範沒有明確指出。只要能存放boolean、byte、char、short、int、float、reference、returnAddress型別的資料就行(小於等於32位)。
Java虛擬機器的資料型別
前6中就不用說了。至於reference只要能夠滿足兩點:
- 通過引用(reference)可以直接或間接的獲取物件在堆中的起始地址
- 通過引用可以直接或間接的獲取物件的所屬型別資訊(在方法區)
就行。而returnAddress現在不怎麼使用了。
64位資料型別long、double
對於64位的資料型別,虛擬機器是分配兩個連續的slot來儲存的。不能單獨的訪問其中任何一個slot,只能一起訪問。
區域性變量表的結構
先是this,然後引數列表,然後區域性變數
原文是這樣說的:
slot的重用
為了節省棧幀空間,slot是可以重用的。在方法體內定義的變數,其作用域不一定覆蓋整個方法體,如果當前PC計數器的值超過了某個變數的作用域,那麼該變數的slot就可以讓其他變數使用了。需要注意的時,Slot複用可能會直接影響垃圾收集行為。
二、運算元棧
運算元棧所需空間大小在編譯階段就確定了。
在概念模型中,棧楨是相互獨立的。但在大多數虛擬機器中都進行了優化,將兩各棧楨打一部分重疊起來。如下所示:
三、動態連線
每一個棧楨都存放了一個指向執行時常量池中該棧楨所屬方法的引用,這樣是為了進行動態連線。這個符號引用存放在棧楨打動態連線中。
靜態解析:就是在類載入階段就進行符號引用解析。
動態連線:就是在程式執行期間就才將符號引用解析為直接引用
四、方法返回地址
方法的退出有兩種方式,無論那種方式,都會返回到方法呼叫位置。
- 正常完成出口:方法正常完成。正常退出,方法返回地址大多數很可能存放在程式計數器中。
- 異常完成出口:方法內部發生異常,並以異常並沒有得到處理。方法打返回地址是由異常異常處理表確定的。
五、附加資訊
《虛擬機器規範》允許虛擬機器的具體實現將一些沒有規定打資訊存到棧楨中去,我們稱為附加資訊。我們把動態連線、方法返回地址、附加資訊一同叫做棧楨資訊。