JVM 執行時棧幀結構

棧幀(Stack Frame)是用於支援虛擬機器進行方法呼叫和方法執行的資料結構,它是虛擬機器執行時資料區中的虛擬機器棧的棧元素。每一個棧幀都包括了局部變量表、運算元棧、動態連線、方法返回地址和一些額外的附加資訊。在編譯程式程式碼的時候,棧幀中需要多大的區域性變量表、多深的運算元棧都已經完全確定了,並且寫入到方法表的 Code 屬性之中。

區域性變量表

區域性變量表是一組變數值儲存空間,用於存放方法引數和方法內部定義的區域性變數。方法 Code 屬性的 max_locals 資料項確定了該方法所需要分配的最大區域性變量表的容量。

區域性變數不存在“準備”階段,如果一個區域性變數定義了但沒有賦初始值是沒法使用的。

賦 null 值的操作在經過虛擬機器 JIT 編譯器最佳化之後會被消除掉。

運算元棧

運算元棧是一個後入先出(LIFO)棧,當一個方法剛剛開始執行的時候,這個方法的運算元棧是空的,在方法的執行過程中,會有各種位元組碼指令向運算元棧中寫入和提取內容,也就是入棧和出棧操作。方法 Code 屬性的 max_stacks 資料項設定了運算元棧的最大深度。

動態連線

Class 檔案常量池中指向方法的符號引用中會有一部分在執行期間轉化為直接引用,這部分稱為動態連線。

與動態連線相對應的是靜態連線。靜態方法、私有方法、例項構造器、父類方法和 final 方法統稱為虛方法,虛方法的呼叫沒有其他版本,無須對方法接收者進行多型選擇,因此它們在類載入的解析階段就會把涉及到的符號引用全部轉變為可確定的直接引用,不會延遲到執行期才去完成。而有些方法,比如過載和重寫方法,具有多個版本,無法直接確定呼叫的是什麼版本,這部分符號引用的轉換就必須等到執行期來完成。

方法返回地址

方法返回地址指的是方法退出後的返回地址。一般來說,方法正常退出時,呼叫者的 PC 計數器的值就可以作為返回地址,棧幀中很可能會儲存這個計數器值。而方法異常退出時,返回地址是要透過異常處理器來確定的,棧幀中一般不會儲存這部分資訊。

附加資訊

附加資訊指的是在虛擬機器實現中加入了一些規範裡沒有描述的資訊到棧幀之中,例如與除錯相關的資訊。