天天看點

深入了解JVM-虛拟機位元組碼執行引擎

8.1 概述

執行引擎是位元組碼是最核心的組成部分之一。執行引擎在執行java代碼的時候,可能會有解釋執行(通過解釋器執行),和編譯執行(通過及時編譯器産生本地代碼執行)二種選擇。但是外觀上看起來是一緻的:輸入的是位元組碼檔案,處理的過程是位元組碼解析的等效過程,輸出的是執行的結果。

8.2 運作時棧幀結構

棧幀是用于支援虛拟機進行方法調用和方法執行的資料結構。棧幀存儲了局部變量表,操作數棧,動态連結和方法傳回位址等資訊和一些額外的附加資訊。

8.2.1 局部變量表

用來存放方法參數和方法内的局部變量。編譯階段就已經确定了局部變量表的大小。局部變量表的容量以變量槽為最小機關。long和double類型要占2個槽,需要分割為2次對記憶體的操作,但是虛拟機可以保證原子性,不允許單獨通路其中的一個位元組。

虛拟機使用局部變量表完成參數值到參數變量表的傳遞。第0個slot預設用來傳遞方法所屬對象的引用。其餘參數暗戰參數表順序排列,占用從第1個開始的局部變量槽。 變量槽是可以重用的,不過這樣的設計,除了會節省空間之外,還可以帶來一些負面影響。1、可能會影響垃圾收集器的行為。2、局部變量表不像類變量一樣,有二次賦初值的過程,第一次在準備階段準備初值。局部變量表沒有準備階段,是以不會用預設的零值。必須賦初值才可以使用。

8.2.2操作數棧

操作數棧的最大深度在編譯階段就已經知道了。操作數棧還可以用來在調用其它參數的時候,傳遞參數。操作數棧中的元素類型必須與指令序列嚴格比對,在編譯階段和驗證階段都會檢查這一點(現在通過StackMapTable實作)。 虛拟機實作會讓二個棧幀出現一部分重疊。讓下面操作數棧與上面棧幀的部分變量表重疊在一起。這樣就可以服用一部分資料,無需進行外的參數複制傳遞。