1. 程式人生 > >科技之星>>>>>>>>>>>>Future

科技之星>>>>>>>>>>>>Future

1、JAVA虛擬機器棧概述

        JAVA虛擬機器棧在JAVA虛擬機器記憶體模型中位置如下圖所示。

        JAVA虛擬機器棧是描述JAVA方法執行的動態記憶體模型。從上圖可以看出虛擬機器棧中包含很多棧幀。

        當虛擬機器棧已記憶體已經使用完了還要繼續給裡面入棧幀,則會出現我們常見的一個錯誤,即java.lang.StackOverflowError.

2、棧幀

        棧幀(stackframe)是用於支援虛擬機器進行方法呼叫和方法執行的資料結構,它是虛擬機器執行時資料區中的虛擬機器棧的棧

元素。棧幀儲存了方法的區域性變量表、運算元棧、動態連線和方法返回地址等資訊。

        每一個方法從呼叫開始到執行完成的過程,就對應著一個棧幀在虛擬機器棧裡面從入棧到出棧的過程。

        對於執行引擎來說,活動執行緒中,只有棧頂的棧幀是有效的,稱為當前棧幀,這個棧幀所關聯的方法稱為當前方法。執行引

擎所執行的所有位元組碼指令都只針對當前棧幀進行操作。

3、棧幀的組成

        接下來對棧幀包含的一些元素進行介紹:

        3.1、區域性變量表
        區域性變量表是一組變數值儲存空間,用於存放方法引數和方法內部定義的區域性變數。在Java程式被編譯成Class檔案時,就在方法的Code屬性的max_locals資料項中確定了該方法所需要分配的。
        3.2、運算元棧
           運算元棧也常被稱為操作棧,它是一個後入先出棧。同區域性變量表一樣,運算元棧的最大深度也是編譯的時候被寫入到方法表的Code屬性的max_stacks資料項中。運算元棧的每一個元素可以是任意Java資料型別,包括long和double。32位資料型別所佔的棧容量為1,64位資料型別所佔的棧容量為2。棧容量的單位為“字寬”,對於32位虛擬機器來說,一個”字寬“佔4個位元組,對於64位虛擬機器來說,一個”字寬“佔8個位元組。        當一個方法剛剛執行的時候,這個方法的運算元棧是空的,在方法執行的過程中,會有各種位元組碼指向運算元棧中寫入和提取值,也就是入棧與出棧操作。例如,在做算術運算的時候就是通過運算元棧來進行的,又或者呼叫其它方法的時候是通過運算元棧來行引數傳遞的。
        3.3、動態連線
        每個棧幀都包含一個指向執行時常量池中該棧幀所屬性方法的引用,持有這個引用是為了支援方法呼叫過程中的動態連線。在Class檔案的常量池中存有大量的符號引用,位元組碼中的方法呼叫指令就以常量池中指向方法的符號引用為引數。這些符號引用一部分會在類載入階段或第一次使用的時候轉化為直接引用,這種轉化稱為靜態解析。另外一部分將在每一次的執行期期間轉化為直接引用,這部分稱為動態連線。
        3.4、方法返回地址
        當一個方法被執行後,有兩種方式退出這個方法。第一種方式是執行引擎遇到任意一個方法返回的位元組碼指令,這時候可能會有返回值傳遞給上層的方法呼叫者(呼叫當前方法的的方法稱為呼叫者),是否有返回值和返回值的型別將根據遇到何種方法返回指令來決定,這種退出方法方式稱為正常完成出口(Normal Method Invocation Completion)。
        另外一種退出方式是,在方法執行過程中遇到了異常,並且這個異常沒有在方法體內得到處理,無論是Java虛擬機器內部產生的異常,還是程式碼中使用athrow位元組碼指令產生的異常,只要在本方法的異常表中沒有搜尋到匹配的異常處理器,就會導致方法退出,這種退出方式稱為異常完成出口(Abrupt Method Invocation Completion)。一個方法使用異常完成出口的方式退出,是不會給它的呼叫都產生任何返回值的。
        無論採用何種方式退出,在方法退出之前,都需要返回到方法被呼叫的位置,程式才能繼續執行,方法返回時可能需要在棧幀中儲存一些資訊,用來幫助恢復它的上層方法的執行狀態。一般來說,方法正常退出時,呼叫者PC計數器的值就可以作為返回地址,棧幀中很可能會儲存這個計數器值。而方法異常退出時,返回地址是要通過異常處理器來確定的,棧幀中一般不會儲存這部分資訊。        方法退出的過程實際上等同於把當前棧幀出棧,因此退出時可能執行的操作有:恢復上層方法的區域性變量表和運算元棧,把返回值(如果有的話)壓入呼叫都棧幀的運算元棧中,呼叫PC計數器的值以指向方法呼叫指令後面的一條指令等。
        3.5、 附加資訊
        虛擬機器規範允許具體的虛擬機器實現增加一些規範裡沒有描述的資訊到棧幀中,例如與高度相關的資訊,這部分資訊完全取決於具體的虛擬機器實現。在實際開發中,一般會把動態連線,方法返回地址與其它附加資訊全部歸為一類,稱為棧幀資訊。