天天看點

JVM知識點整理JVM知識點整理

JVM知識點整理

  1. 描述一下JVM記憶體結構
  2. 每個區的作用是什麼?
  3. 堆記憶體的工作原理是什麼?為什麼需要兩個Survivor區?隻有一個行不行?
  4. 老年代使用什麼垃圾回收算法?

JVM記憶體結構

JVM在執行Java程式的過程中會把它管理的記憶體劃分成若幹不同的資料區域。分析JVM記憶體結構就是分析JVM運作時資料存儲區域

JVM運作時的資料區主要包括:堆、虛拟機棧、方法區、程式計數器、本地方法棧

JVM知識點整理JVM知識點整理

1、堆(GC區)

線程共享

堆是JVM管理記憶體中最大的一塊記憶體區域,堆記憶體被所有線程共享,主要存檔new關鍵字建立的對象,所有對象執行個體以及數組都要在堆上配置設定空間。

垃圾收集器就是根據GC算法,收集堆上所占用的記憶體空間(收集的是對象占用的記憶體空間而不是對象本身)。

堆分為年輕代(Yong Generation)和老年代(Old Generation),年輕代又分為伊甸園區(Eden)和幸存區(Survivor),幸存區又分為From Survivor(S0)和To Survivor(S1)空間。

新建立的對象存儲在年輕代中,當年輕代存滿之後,會觸發Minor GC,清理年輕代記憶體空間。

老年代存儲長期存活的對象和大對象。年輕代中存儲的對象經過多次GC依然存活的對象會移動到老年代存儲。老年代存滿之後會觸發FULL GC。

Minor GC發生在Eden區

Yong GC發生在Eden、S0、S1區

Major GC發生在Old區

FULL GC是清理整個堆空間,包括年輕代和老年代

如果FULL GC之後堆中仍然無法存儲對象,而且堆無法擴充,就發抛出OutOfMemoryError(OOM)錯誤

(1)堆空間比例

預設的,年輕代和老年代的空間比例是1:2,可以通過-XX:NewRatio配置;

預設的,Eden:S0:S1=8:1:1,可以通過-XX:SurvivorRadio配置;

預設的,Survivor中對象被複制的最大次數為15次,可以通過-XX:Max Tenuring Threshold配置;

(2)為什麼年輕代要分成Eden區和Survivor區,為什麼要設定兩個Survivor區

  1. 如果沒有Survivor區,Eden每進行一次Minor GC,存活的對象就會被送入老年代,老年代很快就被填滿,接着觸發Major GC(因為Major GC一般伴随着Minor GC,也可以看成觸發了FULL GC)。由于老年代空間遠大于年輕代,每進行一次FULL GC消耗的時間比Minor GC長的多,影響程式執行、響應速度,是以要區分Eden區和Survivor區。
  2. Survivor區存在的意義就是減少被送到老年代的對象,進而減少FULL GC的發生,Survivor的預篩選保證隻有在Survivor經曆15次複制還能在年輕代存活的對象才會被送到老年代。
  3. 設定兩個Survivor最大的好處就是減少了空間碎片化。如果隻有一塊Survivor區,就會産生下圖這種情況(色塊代表對象占用了的空間)。如果Eden存滿了,Survivor中存了一部分的對象,由于Eden滿了是以會觸發Minor GC,Eden和Survivor中都有一部分的對象存活,接着把Eden中存活的對象轉移到Survivor中,就會導緻空間碎片化。
    JVM知識點整理JVM知識點整理
    如果有兩塊Survivor,假設Eden存滿了,S0中有一部分的對象,由于Eden存滿觸發Minor GC,Eden中存活的對象以及S0中存活的對象會被複制到S1中(S1放不下就放到老年代),Eden以及S0被清空。這樣就保證了Survivor中不會空間碎片化。
    JVM知識點整理JVM知識點整理

2、虛拟機棧

線程私有

是描述java方法執行的記憶體模型。

用于存儲局部變量表、操作數棧、動态連結、方法出口等資訊(存儲臨時變量、基本資料類型、對象的引用位址、方法出口等)。

3、方法區

線程共享

存放已被加載的類的資訊、常量、靜态變量、即時編譯器編譯的代碼資料等(jdk7以前稱為永久代、jdk8之後把它改為中繼資料空間)。回收目标主要是常量池的回收和類型的解除安裝。

4、程式計數器

線程私有

目前線程所執行的位元組碼的行号訓示器,用于記錄正在執行的虛拟機位元組指令位址(存儲程式目前運作的位置)。

為了線程切換可以恢複到正确的位置,每個線程都有獨立的程式計數器,不同線程的程式計數器互不影響,獨立存儲。

如果線程執行java方法,程式計數器記錄的是正在執行的虛拟機位元組指令位址;如果執行的Native方法,計數器值為Undefined。

程式計數器這塊記憶體區域是虛拟機規範中唯一沒有OOM的區域。

5、本地方法棧

線程私有

和虛拟機棧相似,隻不過它服務于Native方法。

參考:

JVM記憶體結構

深入了解JVM-記憶體模型(jmm)和GC

一文搞懂JVM記憶體結構

為什麼新生代記憶體需要有兩個Survivor區

jvm