一、JVM整體架構
根據 JVM 規範,JVM 記憶體共分為虛拟機棧、堆、方法區、程式計數器、本地方法棧五個部分。
JVM分為五大子產品: 類裝載器子系統 、 運作時資料區 、 執行引擎 、 本地方法接口 和 垃圾收集子產品 。
二、JVM運作時記憶體
Java 虛拟機有自動記憶體管理機制,如果出現面的問題,排查錯誤就必須要了解虛拟機是怎樣使用記憶體的。
Java7和Java8記憶體結構的不同主要展現在方法區的實作
方法區是java虛拟機規範中定義的一種概念上的區域,不同的廠商可以對虛拟機進行不同的實作。 我們通常使用的Java SE都是由Sun JDK和OpenJDK所提供,這也是應用最廣泛的版本。而該版本使用的VM就是 HotSpot VM。通常情況下,我們所講的java虛拟機指的就是HotSpot的版本。
JDK7 記憶體結構
JDK8 的記憶體結構
針對JDK8虛拟機記憶體詳解
JDK7和JDK8變化小結
對于Java8,HotSpots取消了永久代,那麼是不是就沒有方法區了呢?
當然不是,方法區隻是一個規範,隻不過它的實作變了。 在Java8中,元空間(Metaspace)登上舞台,方法區存在于元空間(Metaspace)。同時,元空間不再與堆連續,而且是 存在于本地記憶體(Native memory)。
方法區Java8之後的變化
- 移除了永久代(PermGen),替換為元空間(Metaspace)
- 永久代中的class metadata(類元資訊)轉移到了native memory(本地記憶體,而不是虛拟機)
- 永久代中的interned Strings(字元串常量池) 和 class static variables(類靜态變量)轉移到了Java heap
- 永久代參數(PermSize MaxPermSize)-> 元空間參數(MetaspaceSize MaxMetaspaceSize)
Java8為什麼要将永久代替換成Metaspace?
字元串存在永久代中,容易出現性能問題和記憶體溢出。 類及方法的資訊等比較難确定其大小,是以對于永久代的大小指定比較困難,太小容易出現永久代溢出,太 大則容易導緻老年代溢出。 永久代會為 GC 帶來不必要的複雜度,并且回收效率偏低。 Oracle 可能會将HotSpot 與 JRockit 合二為一,JRockit沒有所謂的永久代。