1. 程式人生 > >Java8虛擬機器記憶體模型

Java8虛擬機器記憶體模型

  1. Java虛擬機器執行時資料區

在JDK1.8之前,JVM執行時資料區分為堆、虛擬機器棧、本地方法棧、方法區、程式計數器。如下圖所示:

虛擬機器棧:執行緒私有,隨執行緒建立而建立。棧裡面是一個一個“棧幀”,每個棧幀對應一次方法呼叫。棧幀中存放了區域性變量表(基本資料型別變數和物件引用)、運算元棧、方法出口等資訊。當棧呼叫深度大於JVM所允許的範圍,會丟擲StackOverflowError的錯誤。

本地方法棧:執行緒私有,這部分主要與虛擬機器用到的Native方法相關,一般情況下,並不需要關心這部分的內容。

程式計數器:也叫PC暫存器,JVM支援多個執行緒同時執行,每個執行緒都有自己的程式計數器。倘若當前執行的是 JVM 的方法,則該暫存器中儲存當前執行指令的地址;倘若執行的是native方法,則PC暫存器中為空。(PS:執行緒執行過程中並不都是一口氣執行完,有可能在一個CPU時鐘週期內沒有執行完,由於時間片用完了,所以不得不暫停執行,當下一次獲得CPU資源時,通過程式計數器就知道該從什麼地方開始執行)

方法區:方法區存放類的資訊(包括類的位元組碼,類的結構)、常量、靜態變數等。字串常量池就是在方法區中。雖然Java虛擬機器規範把方法區描述為堆的一個邏輯部分,但是它卻有一個別名叫做Non-Heap(非堆),目的是與Java堆區分開來。很多人都更願意把方法區稱為“永久代”(Permanent Generation)。從jdk1.7已經開始準備“去永久代”的規劃,jdk1.7的HotSpot中,已經把原本放在方法區中的靜態變數、字串常量池等移到堆記憶體中。

堆:堆中存放的是陣列(PS:陣列也是物件)和物件。當申請不到空間時會丟擲OutOfMemoryError。

  1. PermGen(永久代)

“方法區”是JVM的規範,而“永久代”是方法區的一種實現,並且只有HotSpot才有“PermGen space”,而對於其他型別的虛擬機器並沒有“PermGen space”。

在JDK1.8中,HotSpot已經沒有“PermGen space”這個區間了,取而代之是Metaspace(元空間)

  1. Metaspace(元空間)

在JDK1.8中,永久代已經不存在,儲存的類資訊、編譯後的程式碼資料等已經移動到了MetaSpace(元空間)中,元空間並沒有處於堆記憶體上,而是直接佔用的本地記憶體(NativeMemory)。

元空間的本質和永久代類似,都是對JVM規範中方法區的實現。

不過元空間與永久代之間最大的區別在於:元空間並不在虛擬機器中,而是使用本地記憶體。

元空間的大小僅受本地記憶體限制,可以通過以下引數來指定元空間大小:

-XX:MetaspaceSize,初始空間大小,達到該值就會觸發垃圾收集進行型別解除安裝,同時GC會對該值進行調整:如果釋放了大量的空間,就適當降低該值;如果釋放了很少的空間,那麼在不超過MaxMetaspaceSize時,適當提高該值
-XX:MaxMetaspaceSize,最大空間,預設是沒有限制的
-XX:MinMetaspaceFreeRatio,在GC之後,最小的Metaspace剩餘空間容量的百分比,減少為分配空間所導致的垃圾收集
-XX:MaxMetaspaceFreeRatio,在GC之後,最大的Metaspace剩餘空間容量的百分比,減少為釋放空間所導致的垃圾收集

  1. 堆記憶體劃分

在JDK1.7以及其前期的JDK版本中,堆記憶體通常被分為三塊區域:Young Generation、Old Generation、Permanent Generation for VM Matedata

在JDK1.8中把存放元資料中的永久記憶體從堆記憶體中移到了本地記憶體中,JDK1.8中JVM堆記憶體結構就變成了如下:

  1. 堆統計資訊

  2. 其它相關

《利用jmap和MAT等工具檢視JVM執行時堆記憶體》

  1. 參考

https://blog.csdn.net/qq_31337311/article/details/78799262

https://www.cnblogs.com/paddix/p/5309550.html

https://blog.csdn.net/zwrlj527/article/details/79399715 歡迎工作一到五年的Java工程師朋友們加入Java群: 891219277
群內提供免費的Java架構學習資料(裡面有高可用、高併發、高效能及分散式、Jvm效能調優、Spring原始碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!