目錄
- 垃圾標記
- 參考計數法
- 可達性分析(主流使用)
- GC回收演算法
- 標記-清除演算法(適合老年代)
- 標記-復制演算法(適合年輕代)
- 標記-整理演算法(適合老年代)
- “因地制宜”——分代演算法
- GC回收器
- Serial 回收器
- Serial Old 回收器
- ParNew回收器
- Parallel Old回收器
- Parallel Scavenge回收器
- CMS收集器
- G1回收器
垃圾標記
在回收垃圾前,需要判斷哪些是垃圾,哪些不是,
參考計數法
原理:被參考+1,未被參考-1,為0時回收,
問題:無法解決回圈參考的問題
-
什么是回圈參考?(環)
A 參考了 B,B 參考了 C,C 參考了 A,它們各自的參考計數都為 1,但是它們三個物件卻從未被其他物件參考,(假設有1000個物件時,這三個就是垃圾;如果只有4個物件,那么另外一個就是垃圾)只有它們自身互相參考,從垃圾的判斷思想來看,它們三個確實是不被其他物件參考的,但是此時它們的參考計數卻不為零,
可達性分析(主流使用)
通過GC Roots作為起點遍歷,判斷是否被參考,
GC Roots包括:
- 虛擬機堆疊中參考的物件
- 方法區靜態屬性參考的物件
- 方法區常量參考的物件
- JNI參考的物件(Native方法)
【參考的判定】
- 強參考:拋例外也不回收
- 軟參考:記憶體空間不夠就回收
- 弱參考:發現了就回收(按執行緒優先級)
- 虛參考:任何時刻都會被回收
GC回收演算法
分代收集本質上就是分類討論,根據對存活物件的預判,采用效率更高的收集演算法,
標記-清除演算法(適合老年代)
先通過GC Roots遍歷,標記不可達物件,而后清除,
問題:產生不連續的空間碎片
標記-復制演算法(適合年輕代)
折半記憶體,將存活物件復制到另一半記憶體中,然后把當前記憶體全部回收,
問題:解決了空間碎片,但只能使用一半的記憶體
標記-整理演算法(適合老年代)
將存活物件移動到記憶體的一端,然后清除邊界之外的所有記憶體,
【既不會產生空間碎片,也不會導致記憶體折半】
“因地制宜”——分代演算法
分代演算法,就是根據 JVM 記憶體的不同記憶體區域,采用不同的垃圾回收演算法,
例如對于存活物件少的新生代區域,比較適合采用復制演算法,這樣只需要復制少量物件,便可完成垃圾回收,并且還不會有記憶體碎片,
而對于老年代這種存活物件多的區域,比較適合采用標記清除演算法或標記整理演算法,這樣不需要移動太多的記憶體物件,
GC回收器
Serial 回收器
Serial回收器是一種單執行緒串行回收器,使用復制演算法,在執行回收時會產生較長時間的停頓,優點是不會產生執行緒切換的開銷
通過JVM引數-XX:+UseSerialGC可以使用串行垃圾回收器,
Serial Old 回收器
SO回收器是一種多執行緒并行回收器,使用標記整理演算法,適用老年代
ParNew回收器
PN回收器是一種多執行緒并行器,使用復制演算法,
引數控制:-XX:+UseParNewGC
Parallel Old回收器
PO是一種多執行緒回收器,使用標記整理演算法,適用老年代
Parallel Scavenge回收器
PS回收器也是一種多執行緒并行回收器,使用復制演算法,特點是可設定吞吐量
引數:-XX:+UseParallelGC
CMS收集器
CMS使用標記清除演算法,主要目的是回收時的低停頓,
程序:
- 初始標記:單執行緒(觸發停頓),標記與GC Roots關聯的物件
- 并發標記:標記不可達物件(可能產生回收物件,所以之后需要重新標記)
- 重新標記:單執行緒(觸發停頓),糾正標記
- 并發清除:清除物件
問題:
- CPU資源消耗高
- 浮動垃圾產生(回收時產生了新的垃圾)
- 標記清除演算法導致的空間碎片問題
G1回收器
特點:
- 停頓時間:G1可充分利用多核多CPU的優勢減少停頓時間,并且可建立可以預測的停頓模型,可設定停頓的時間
- 支持分代回收,可使用磁區策略同時兼顧老年代和年輕代
- 使用標記整理演算法,不會產生空間碎片
磁區思路:
為什么使用磁區:針對老年代的操作需要掃描所有的老年代空間;由于連續,必須分配年輕代和老年代的地址位置
G1之前的記憶體都是連續的:

G1回收器的記憶體按區等分,分為eden,survivor,old和humongous:

G1回收器回收流程:
- 初始標記
- 并發標記
- 重新標記
- 并發回收
Minor GC 和Full GC
從年輕代空間(包括 Eden 和 Survivor 區域)回收記憶體被稱為 Minor GC,當 JVM 無法為一個新的物件分配空間時會觸發 Minor GC,比如當 Eden 區滿了,
Full GC 是清理整個堆空間—包括年輕代和永久代,
Full GC執行條件:
- 呼叫System.gc時,系統建議執行Full GC,但是不必然執行
- 老年代空間不足
- 方法區空間不足
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/103721.html
標籤:Java
下一篇:JVM類加載機制
