在Java8和之後版本中JVM的內存結構慢慢發生了變化。做爲面試官若是你還不知道,那麼面試過程當中是否是有些露怯?做爲面試者,若是知曉這些變化,又將成爲面試中的亮點。java
若是在網絡上搜索JVM內存結構,90%的可能會搜到Java7及之前的內存圖,本篇文章將會對JVM內存結構再次細化,深刻理解Java8以後的內部變化。如今意×××」的好處了吧。在這裏能夠不斷的刷新你的知識和認知。程序員
來看一下JVM中的內存結構圖。面試
爲了更細化的講解,咱們將該圖進行進一步的優化調整。針對java7及之前版本的細化。安全
看出變化了嗎?堆和方法區連在了一塊兒,但這並不能說堆和方法區是一塊兒的,它們在邏輯上依舊是分開的。但在物理上來講,它們又是連續的一塊內存。也就是說,方法區和前面講到的Eden和老年代是連續的。網絡
在繼續進行下去以前,咱們先來理解兩個概念:規範和實現。運維
針對Java虛擬機的實現有專門的《Java虛擬機規範》,在遵照規範的前提下,不一樣的廠商會對虛擬機進行不一樣的實現。 就比如開發的過程當中定義了接口,具體的接口實現你們能夠根據不一樣的業務需求進行實現。ide
PS:你們都有必要了解一下《Java虛擬機規範×××」,回覆「002」得到Java SE 7的虛擬機規範PDF版。性能
咱們一般使用的Java SE都是由Sun JDK和OpenJDK所提供,這也是應用最普遍的版本。而該版本使用的VM就是HotSpot VM。一般狀況下,咱們所講的java虛擬機指的就是HotSpot的版本。測試
上面理解了規範和實現以後,來看認識一個概念「永久代(Permanet Generation,也稱PermGen)」。對於習慣了在HotSpot虛擬機上開發、部署的程序員來講,不少都願意將方法區稱做永久代。優化
本質上來說二者並不等價,僅由於Hotspot將GC分代擴展至方法區,或者說使用永久代來實現方法區。在其餘虛擬機上是沒有永久代的概念的。也就是說方法區是規範,永久代是Hotspot針對該規範進行的實現。
理解上面的概念以後,咱們對Java7及之前版本的堆和方法區的構造再進行一下變更。
再重複一遍就是對Java7及之前版本的Hotspot中方法區位於永久代中。同時,永久代和堆是相互隔離的,但它們使用的物理內存是連續的。
永久代的垃圾收集是和老年代捆綁在一塊兒的,所以不管誰滿了,都會觸發永久代和老年代的垃圾收集。
但在Java7中永久代中存儲的部分數據已經開始轉移到Java Heap或Native Memory中了。好比,符號引用(Symbols)轉移到了Native Memory;字符串常量池(interned strings)轉移到了Java Heap;類的靜態變量(class statics)轉移到了Java Heap。
而後,在Java8中,時代變了,Hotspot取消了永久代。永久代真的成了永久的記憶。永久代的參數-XX:PermSize和-XX:MaxPermSize也隨之失效。
對於Java8,HotSpots取消了永久代,那麼是否是就沒有方法區了呢?固然不是,方法區只是一個規範,只不過它的實現變了。
在Java8中,元空間(Metaspace)登上舞臺,方法區存在於元空間(Metaspace)。同時,元空間再也不與堆連續,並且是存在於本地內存(Native memory)。
本地內存(Native memory),也稱爲C-Heap,是供JVM自身進程使用的。當Java Heap空間不足時會觸發GC,但Native memory空間不夠卻不會觸發GC。
針對Java8的調整,咱們再次對內存結構圖進行調整。
元空間存在於本地內存,意味着只要本地內存足夠,它不會出現像永久代中「java.lang.OutOfMemoryError: PermGen space」這種錯誤。看上圖中的方法區,是否是「膨脹」了。
默認狀況下元空間是能夠無限使用本地內存的,但爲了避免讓它如此膨脹,JVM一樣提供了參數來限制它使用的使用。
思考一下,爲何使用元空間替換永久代?
表面上看是爲了不OOM異常。由於一般使用PermSize和MaxPermSize設置永久代的大小就決定了永久代的上限,可是不是總能知道應該設置爲多大合適, 若是使用默認值很容易遇到OOM錯誤。
當使用元空間時,能夠加載多少類的元數據就再也不由MaxPermSize控制, 而由系統的實際可用空間來控制。
更深層的緣由仍是要合併HotSpot和JRockit的代碼,JRockit歷來沒有所謂的永久代,也不須要開發運維人員設置永久代的大小,可是運行良好。同時也不用擔憂運行性能問題了,在覆蓋到的測試中, 程序啓動和運行速度下降不超過1%,可是這點性能損失換來了更大的安全保障。
通過上面的講解和演變,是否是對JVM的內存結構有了更深的理解了?能夠和麪試官多聊一下子了,畢竟面試官的時間也很少了。