聊聊 Java(一):執行時資料區
根據《Java 虛擬機器規範(Java SE 8 版)》中,Java 執行時資料區主要分為:
- PC 暫存器
- Java 虛擬機器棧
- Java 堆
- 方法區
- 執行時常量池
- 本地方法棧
PC 暫存器
Java 虛擬機器可以支援多條執行緒同時執行,每一個 Java 虛擬機器執行緒都有自己的 PC 暫存器(Program Counter Register)。
在任意時刻,一個 Java 虛擬機器執行緒只會執行一個方法的程式碼,這個正在被執行緒執行的方法稱為當前方法。如果當前方法不是 Native 方法,PC 暫存器就儲存 Java 虛擬機器正在執行的位元組碼指令的地址。如果當前方法時 Native 方法,PC 暫存器的值是 undefined。
Java 虛擬機器棧
每一個 Java 虛擬機器執行緒都有自己私有的 Java 虛擬機器棧(Java Virtual Machine Stack),這個棧與執行緒同時建立,用於儲存棧幀(Frame)。
棧幀隨著方法的呼叫而建立,隨著方法的結束而銷燬。棧幀用於儲存區域性變量表、運算元棧、動態連結和方法出口等資訊。
如果執行緒請求分配的棧容量超過了 Java 虛擬機器允許的最大容量,Java 虛擬機器將會丟擲一個 StackOverflowError
異常。如果 Java 虛擬機器棧可以動態擴充套件,並且在嘗試擴充套件的時候無法申請到足夠的記憶體,或者在建立新的執行緒時沒有足夠的記憶體去建立對應的虛擬機器棧,那麼 Java 虛擬機器將會丟擲一個 OutOfMemoryError
異常。
Java 堆
在 Java 虛擬機器中,堆(Heap)是可供各個執行緒共享的執行時記憶體區域,也是供所有類例項和陣列物件分配記憶體的區域。
Java 堆是垃圾收集器管理的主要區域。從記憶體回收的角度看,由於收集器基本都採用了分代收集演算法,所以 Java 堆可以分為:新生代(Young Generation)和老年代(Old Generation 或 Tenured Generation)。新生代又可以細分為 Eden 空間和 Survivor 空間。
注:Java 8 之後,沒有了永久代(Permanent Generation),取而代之的是元空間(Metaspace)。元空間不在 Java 堆上,而在本地記憶體上。
方法區
在 Java 虛擬機器中,方法區(Method Area)是可供各個執行緒共享的執行時記憶體區域,用於儲存已被虛擬機器載入的類的結構資訊。例如,執行時常量池、欄位和方法資料、建構函式和普通方法的位元組碼內容,還包括一些在類、例項、介面初始化時用到的特殊方法。
執行時常量池
執行時常量池(Runtime Constant Pool)是 class 檔案中每一個類或介面的常量池的執行時表示形式,它包括了若干種不同的常量,從編譯期可知的數值字面量到必須在執行期才能獲得的方法或欄位引用。
本地方法棧
Java 虛擬機器實現可能會使用到傳統的棧(通常稱為 C Stack)來支援 native 方法的執行,這個棧就是本地方法棧(Native Method Stack)。當 Java 虛擬機器使用其他語言(例如 C 語言)來實現指令集直譯器時,也可以使用本地方法棧。