科技之星>>>>>>>>>>>>Future
阿新 • • 發佈:2018-12-09
1、JAVA虛擬機器棧概述
JAVA虛擬機器棧在JAVA虛擬機器記憶體模型中位置如下圖所示。
JAVA虛擬機器棧是描述JAVA方法執行的動態記憶體模型。從上圖可以看出虛擬機器棧中包含很多棧幀。
當虛擬機器棧已記憶體已經使用完了還要繼續給裡面入棧幀,則會出現我們常見的一個錯誤,即java.lang.StackOverflowError.
2、棧幀
棧幀(stackframe)是用於支援虛擬機器進行方法呼叫和方法執行的資料結構,它是虛擬機器執行時資料區中的虛擬機器棧的棧
元素。棧幀儲存了方法的區域性變量表、運算元棧、動態連線和方法返回地址等資訊。
每一個方法從呼叫開始到執行完成的過程,就對應著一個棧幀在虛擬機器棧裡面從入棧到出棧的過程。
對於執行引擎來說,活動執行緒中,只有棧頂的棧幀是有效的,稱為當前棧幀,這個棧幀所關聯的方法稱為當前方法。執行引
擎所執行的所有位元組碼指令都只針對當前棧幀進行操作。
3、棧幀的組成
接下來對棧幀包含的一些元素進行介紹:
3.1、區域性變量表
區域性變量表是一組變數值儲存空間,用於存放方法引數和方法內部定義的區域性變數。在Java程式被編譯成Class檔案時,就在方法的Code屬性的max_locals資料項中確定了該方法所需要分配的。3.2、運算元棧
3.3、動態連線
3.4、方法返回地址
當一個方法被執行後,有兩種方式退出這個方法。第一種方式是執行引擎遇到任意一個方法返回的位元組碼指令,這時候可能會有返回值傳遞給上層的方法呼叫者(呼叫當前方法的的方法稱為呼叫者),是否有返回值和返回值的型別將根據遇到何種方法返回指令來決定,這種退出方法方式稱為正常完成出口(Normal Method Invocation Completion)。另外一種退出方式是,在方法執行過程中遇到了異常,並且這個異常沒有在方法體內得到處理,無論是Java虛擬機器內部產生的異常,還是程式碼中使用athrow位元組碼指令產生的異常,只要在本方法的異常表中沒有搜尋到匹配的異常處理器,就會導致方法退出,這種退出方式稱為異常完成出口(Abrupt Method Invocation Completion)。一個方法使用異常完成出口的方式退出,是不會給它的呼叫都產生任何返回值的。
無論採用何種方式退出,在方法退出之前,都需要返回到方法被呼叫的位置,程式才能繼續執行,方法返回時可能需要在棧幀中儲存一些資訊,用來幫助恢復它的上層方法的執行狀態。一般來說,方法正常退出時,呼叫者PC計數器的值就可以作為返回地址,棧幀中很可能會儲存這個計數器值。而方法異常退出時,返回地址是要通過異常處理器來確定的,棧幀中一般不會儲存這部分資訊。 方法退出的過程實際上等同於把當前棧幀出棧,因此退出時可能執行的操作有:恢復上層方法的區域性變量表和運算元棧,把返回值(如果有的話)壓入呼叫都棧幀的運算元棧中,呼叫PC計數器的值以指向方法呼叫指令後面的一條指令等。