一文讀懂 - 元空間和永久代

爲何JDK8中永久代 離家出走,元空間 鳩佔鵲巢,爲何永久代要離開,永久代和元空間究竟是何方神聖?

歡迎走進今天的《走近科學》,呸,走進今天的《一文讀懂 - 元空間和永久代》java


\color{GoldenRod}{1,看圖說話}

Java7及之前版本的細化JVM結構圖程序員

從圖中能夠看出,在7以及以前堆和方法區連在了一塊兒,但這並不能說堆和方法區是一塊兒的,它們在邏輯上依舊是分開的。但在物理上來講,它們又是連續的一塊內存,下面的圖可能能夠幫助咱們更好的理解。 安全

\color{GoldenRod}{2,什麼是永久代(PermGen)}

首先咱們來認識一下永久代的概念性能

「永久代(Permanet Generation,也稱PermGen)」。對於習慣了在HotSpot虛擬機上開發、部署的程序員來講,不少人都願意將方法區稱做永久代。測試

本質上來說二者並不等價,僅由於Hotspot將GC分代擴展至方法區,或者說使用永久代來實現方法區。在他虛擬機上是沒有永久代的概念的,永久代是Hotspot針對該規範進行的實現。spa

什麼是HotSpot:咱們一般使用的Java SE都是由Sun JDK和OpenJDK所提供,這也是應用最普遍的版本。 而該版本使用的VM就是HotSpot VM。簡單來講,咱們所講的java虛擬機指的就是HotSpot的版本。3d

再重複一遍就是,Java7及之前版本的Hotspot中方法區位於永久代中。同時,永久代和堆是相互隔離的,但它們使用的物理內存是連續的。cdn

小Tip:永久代的垃圾收集是和老年代捆綁在一塊兒的,所以不管誰滿了,都會觸發永久代和老年代的垃圾收集。blog

而後,在Java8中,時代變了,Hotspot取消了永久代。ip

永久代真的成了永久的記憶。永久代的參數-XX:PermSize和-XX:MaxPermSize也隨之失效。

\color{GoldenRod}{3,元空間又是誰}

對於Java8,HotSpots取消了永久代,那麼是否是就沒有方法區了呢?

固然不是,方法區只是一個規範,只不過它的實現變了。

在Java8中,元空間(Metaspace)鳩佔鵲巢,方法區存在於元空間(Metaspace)。

同時,元空間再也不與堆連續,並且是存在於本地內存(Native memory)。

針對Java8的調整,咱們再次對內存結構圖進行調整。

元空間存在於本地內存,意味着只要本地內存足夠,它不會出現像永久代中的 「java.lang.OutOfMemoryError: PermGenspace」

默認狀況下元空間是能夠無限使用本地內存的,但爲了避免讓它如此膨脹,JVM一樣提供了參數來限制它使用的使用。

  • -XX:MetaspaceSize,class metadata的初始空間配額,以bytes爲單位,達到該值就會觸發垃圾收集進行類型卸載,同時GC會對該值進行調整:若是釋放了大量的空間,就適當的下降該值;若是釋放了不多的空間,那麼在不超過MaxMetaspaceSize(若是設置了的話),適當的提升該值。

  • -XX:MaxMetaspaceSize,能夠爲class metadata分配的最大空間。默認是沒有限制的。

  • -XX:MinMetaspaceFreeRatio,在GC以後,最小的Metaspace剩餘空間容量的百分比,減小爲class metadata分配空間致使的垃圾收集。

  • -XX:MaxMetaspaceFreeRatio,在GC以後,最大的Metaspace剩餘空間容量的百分比,減小爲class metadata釋放空間致使的垃圾收集。

\color{GoldenRod}{4,爲何永久代離開了}

表面上看是爲了不OOM異常。由於一般使用PermSize和MaxPermSize設置永久代的大小就決定了永久代的上限,可是不是總能知道應該設置爲多大合適, 若是使用默認值很容易遇到OOM錯誤。

當使用元空間時,能夠加載多少類的元數據就再也不由MaxPermSize控制, 而由系統的實際可用空間來控制。

更深層的緣由仍是要合併HotSpot和JRockit的代碼,使用了元空間取代永久代,不用擔憂運行性能問題了,在覆蓋到的測試中, 取代後程序啓動和運行速度下降不超過1%,可是這點性能損失換來了更大的安全保障。


文章參考:

1,Monica Beckwith 《永久代去哪了了?》

2,程序新視界,醜胖俠二師兄

3,深刻理解Java虛擬機(第2版)


若是文章對你有幫助,記得文末點贊哦!

相關文章
相關標籤/搜索