JVM 運行時棧幀結構

棧幀(Stack Frame)是用於支持虛擬機進行方法調用和方法執行的數據結構,它是虛擬機運行時數據區中的虛擬機棧的棧元素。每一個棧幀都包括了局部變量表、操作數棧、動態連接、方法返回地址和一些額外的附加信息。在編譯程序代碼的時候,棧幀中需要多大的局部變量表、多深的操作數棧都已經完全確定了,並且寫入到方法表的 Code 屬性之中。

局部變量表

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

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

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

操作數棧

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

動態連接

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

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

方法返回地址

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

附加信息

附加信息指的是在虛擬機實現中加入了一些規範裡沒有描述的信息到棧幀之中,例如與調試相關的信息。


分享到:


相關文章: