Java運行時資料區

來源:互聯網
上載者:User

標籤:img   類型   method   長度   nat   地方法   線程   時間   連續   

Java虛擬機器定義了一些程式運行期間會使用到的資料區域,其中一些會隨著JVM的啟動而建立,隨著JVM的退出而銷毀;另外一些則與線程的運行一一對立的,這些資料區域會隨著線程的開始而建立,隨著線程的結束而銷毀。下面是一張Java運行時的資料區模型圖:

總的來說,Java運行時資料區域可以分為兩個部分:線程共用的地區和線程獨享的地區。下面一一對之進行總結。

一、線程共用地區:線程共用地區是指各個線程都會使用到的一塊空間地區,它們會在這裡申請空間、使用空間。根據具體提供功能不同,可以劃分為兩個部分,分別是Java堆、方法區。下面分別總結。

1、Java堆:Java堆是在虛擬機器啟動的時候就被建立,它儲存了被自動記憶體管理系統(也即常說的垃圾收集器)所管理的各種對象,這些對象無需也無法被顯示地銷毀。我們建立的類的執行個體以及數組對象就存放在這個地區。Java堆所使用的記憶體不需要保證是連續的。Java堆可能出現的異常有:如果所需的堆超過了自動記憶體管理系統能提供的最大容量,則Java虛擬機器會拋出一個OutOfMemoryError異常。

2、方法區:方法區也是供各個線程共用的運行時儲存區,它儲存了每一個類的結構下資訊,例如運行時常量池、欄位和方法資料、建構函式和普通方法的位元組碼內容等。方法區也是隨著虛擬機器的啟動而被建立,它是Java堆的邏輯組成部分,但是JVM可以選擇在這個地區不實行垃圾搜集和壓縮。同樣,如果方法區的記憶體不能滿足記憶體配置需求,則JVM將會拋出OutOfMemoryError異常。

3、運行時常量池:它是Class檔案中每一個類或介面的常量池表的運行時的表示形式。它包涵了若干不同的常量,從編譯期可知的數值字面量到必須在運行期解析後才能獲得的方法或欄位引用。每個運行時常量池都在Java虛擬機器的方法區分配,在類和介面載入到虛擬機器後,就會建立對應的運行時常量池。當建立類和介面時,如果構造運行時常量池所需的記憶體空間超過了方法區所提供的最大值,JVM將會拋出OutOfMemoryError異常。

二、線程獨享地區:線程獨享地區是每個線程都會單獨擁有的一塊地區,這塊地區是屬於線程內部的,它是用於儲存描述自身內部資訊的地區。同樣,根據其提供 主要功能不同,一個線程內部具有的不同資料存放區地區可以分為以下幾個部分:

1、PC寄存器:PC(program counter)寄存器是用於記錄正在執行線程的記憶體位址的,因為一個線程不可能一直獨享CPU,當線程進行CPU切換時,必須要記錄下來當前線程的記憶體位址,以便在重新啟動線程時恢複以前的記憶體位址,在任意時刻,一條線程只會執行一個方法的代碼,這個正在被執行的方法被成為該線程的當前方法(current method)。如果這個方法不是native的,那麼PC寄存器會儲存JVM正在執行的位元組碼指令的地址;如果該方法是native的,那麼PC寄存器的值是undefined。

2、本地方法戰:JVM可能會使用傳統的棧(通常稱為 C stack)來支援native方法(指使用Java以外的其他語言編寫的方法)的執行,這個棧就是本地方法棧(native method stack)。JVM規範允許本地方法棧實現成為固定大小或者根據計算來動態擴充和收縮。若採用固定大小的本地方法棧,則每一個線程的本地方法容量可以在建立棧的時候獨立選定。

3、Java虛擬機器棧:也就是常說的“Java棧”,每一個JVM線程都有自己私人的Java虛擬機器棧,該棧是與線程同時建立,用於儲存棧幀。它的作用是用於儲存一些尚未計算好的結果,此外,它在方法的調用和返回中也具有重要的作用。JVM規範既允許java虛擬機器棧被是現成固定大小,也允許根據計算來擴充和收縮。若採用固定大小的Java虛擬機器棧,則每一個線程的Java虛擬機器棧容量可以線上程建立的時候獨立選定。Java虛擬機器棧可能發生的異常有:如果線程請求的棧容量超過java虛擬機器棧所允許的最大容量,則java虛擬機器會拋出StackOverflowError異常;如果java虛擬機器棧可以動態擴充,並且在嘗試擴充的時候無法申請到足夠的記憶體或則建立新的線程時沒有足夠的記憶體去建立對應的虛擬機器棧,則java虛擬機器會拋出OutOfMemoryError異常。

4、棧幀:棧幀(frame)是用來儲存資料和部分過程結果的資料結構。同時也是用來處理動態連結(dynamic linking)、方法傳回值和異常指派。棧幀隨著方法的調用而被建立,隨著方法的結束而被銷毀(無論是方法正常完成還是異常完成)。棧幀的儲存空間是由建立它的線程分配在java虛擬機器棧中的。每一個棧幀都有自己的本地變數表(local variable)、運算元棧(operand stack)、指向當前方法所屬的類的運行時常量池的引用。在某個線程執行過程中的某個時間點上,只有目前正在執行的那個方法的棧幀是活動的,這個棧幀被成為當前棧幀(current frame),這個棧幀對應的方法稱為當前方法(current method)、定義這個方法的類稱為當前類(current class)。注意:棧幀是執行緒區域私人的資料,不能在一個棧幀之中引用另外一個線程的棧幀。

5、局部變數表:也叫本地變數表,它是用於儲存局部變數的列表。棧幀中的局部變數表的長度是由編譯期決定,並儲存與類或介面的二進位表示中。一個局部變數可以儲存一個類型為boolean、byte、char、short、int、float的資料類型。兩個局部變數可以儲存一個類型為long或double的資料。JVM使用局部變數表來完成方法調用時的參數傳遞。

6、運算元棧:每個棧幀內部均包含一個運算元棧,棧幀在剛被建立的時候,運算元棧是空的。JVM提供一些位元組碼指令來從局部變數表或者對象的執行個體中複製常量或變數到運算元棧中,也提供了相關指令從運算元棧中取走資料、操作資料以及把操作結果重新入棧。任意時刻,運算元棧都會有一個確定的棧深度,一個long、double類型的資料會佔用兩個深度的棧深度,其他資料則會佔用一個棧深度。

6、動態連結:每個棧幀都包含這樣一個引用,該引用是指向當前方法所在類型的運行時常量池,其作用是對當前代碼實現動態連結。一個方法要調用其他方法,或則訪問成員變數,需要通過符號引用(symbolic reference)來表示,動態連結的作用就是將這些以符號引用所表示的方法轉換為對實際方法的直接引用。由於對其他類中的方法和變數進行了晚期綁定(late binding),所以即便那些類發生變化,也不會影響調用它們的方法。

以上總結自《Java虛擬機器規範》,感覺內容還是挺多的,加油!

 

Java運行時資料區

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.