Java虛擬機器記憶體區域劃分

以java起始發表於2018-07-19

我們知道,Java虛擬機器在Java程式執行時會將其所管理的記憶體劃分為多個區域。這些區域各自擁有著自己的生命週期與作用,下圖為《Java虛擬機器規範(第二版)》所描述分佈圖:

 

一:程式計數器

程式計數器,是一塊較小的記憶體空間,它是當前執行緒所執行位元組碼的行號指示器。不同執行緒之間,有著各自的計數器。彼此互不干擾,屬於執行緒私有。此外,在本區域不會出現OutOfMemoryError,也是唯一一個不會出現該異常的區域。

二:虛擬機器棧

Java虛擬機器棧,也是執行緒私有,其生命週期與執行緒相同。虛擬機器棧描述了Java方法執行模型,說明了Java方法執行過程中,會建立一個棧幀,用於儲存區域性變數表,運算元棧,動態連結,方法出口等相關資訊,方法執行的一個完整過程,代表著棧幀在棧中的入棧和出棧過程。在粗糙的棧和堆的分配認知裡,程式設計師所關注的棧,其實嚴格意義上多數指的就是虛擬機器棧中的區域性變數表。區域性變數表儲存的是基本變數型別,物件引用型別,returnAdress型別。區域性變數表所需記憶體空間,在編譯期就是確定的。執行時不會改變。

該區域可能發生兩種異常:OutOfMemoryError異常或Stack Overflow異常

三:本地方法棧

本地方法棧與虛擬機器棧類似,但其服務物件為Native方法,不一樣的虛擬機器可能會把兩者合二為一

四:Java堆

Java堆理論上是虛擬機器記憶體最大的一塊區域,其所為各個執行緒共享。它唯一的目的就是存放各物件例項,所以在當前的虛擬機器中,幾乎所有的物件都是在該區域分配。該區域在物理空間不連續,保留邏輯空間連續即可,同時,該區域可以擴充。

Java堆是作為垃圾回收的主要區域,基於不同的垃圾回收演算法機制,可能該區域詳細劃分並不一樣;這裡主要說明分代收集演算法的詳細劃分。如圖是分代收集演算法下的堆記憶體詳細劃分圖:

此處我們僅做分代劃分說明,垃圾回收詳細,待下次說明。

五:方法區

該區域同樣為各執行緒共享區域,主要存放裝載的類資訊,常量,靜態變數,即時編譯的位元組碼等資訊。Java虛擬機器規範對該區域保留最大的寬鬆要求,Java虛擬機器規範將此區域描述為堆的邏輯部分,但事實上,這塊區域有自己獨特的性質。儘管該區域存在垃圾回收的機率小,但還是會有一部分東西被回收。在本區域,被回收的目標主要針對常量池與型別的解除安裝。

該區域同樣可能發生OutOfMemoryError異常。

六:執行時常量池

常量池,是屬於方法區的一部分,用於存放編譯期生成的各種字面量與符號引用。執行時常量池具備動態性,執行時新的常量,也可以存入常量池中,可能發生OutOfMemoryError異常。

 

參考:

          周志明:《深入理解Java虛擬機器(JVM高階特性與最佳實踐)》

相關文章