1. 程式人生 > 其它 >常見的垃圾回收器

常見的垃圾回收器

1.JDK誕生

Serial追隨 提高效率,誕生了PS,為了配合CMS,誕生了PN,CMS是1.4版本後期引入,CMS是里程碑式的GC,它開啟了併發回收的過程,但是CMS毛病較多,因此目前沒有任何一個JDK版本預設是CMS併發垃圾回收,是因為無法忍受STW(Stop-The-World)

1.1 年輕代 序列回收

單CPU效率最高,虛擬機器是Client模式的預設垃圾回收器。Serial回收器使用單執行緒進行垃圾回收,使用複製演算法。在 HotSpot 虛擬機器中,使用-XX:+UseSerialGC 引數可以指定使用Serial(新生代序列收集器)+ Serial Old(老年代序列收集器)。


1.2PS年輕代 並行回收

新生代並行回收收集器也是使用複製演算法的收集器。從表面上看,它和並行收集器一樣都是多執行緒、獨佔式的收集器。但是,並行回收收集器有一個重要的特點:它非常關注系統的吞吐量。
在啟動引數中指定-XX:+UseParallelGC,會使用Parallel Scavenge(新生代並行回收收集器) + SerialOld的回收器組合
如果使用-XX:+UseParallelOldGC,表示Parallel Scavenge(新生代並行回收收集器)+ Parallel Old(並行回收收集器)

1.3ParNew年輕代

配合CMS的並行回收 Serial回收器的多執行緒版本,只能用於新生代。使用複製演算法,多執行緒並行工作。在多CPU主機上的效能高於Serial,單CPU主機上的效能低於Serial。
如果使用-XX:+UseParNewGC,表示ParNew(並行收集器)+ Serial Old(序列收集器)

1.4SerialOld老年代

序列回收Serial收集器的老年版本,獨佔式,單執行緒,使用的是標記--整理演算法,這個收集器的目的也是用於Client模式下的虛擬機器使用。

1.5ParallelOld老年代 並行回收

是Parallel Scavenge收集器的老年版本,使用多執行緒和標記整理演算法,注重吞吐量優先,在注重吞吐量和CPU資源銘感的場合,都可以考慮Parallel Scavenge加Parallel Old收集器。


1.6ConcurrentMarkSweep老年代 併發的, 垃圾回收和應用程式同時執行,降低STW的時間(200ms)

演算法:三色標記 + Incremental Update
1.初始標記:Stop the world,只標記GC Roots能直接關聯到的物件。
2.併發標記:GC Roots Tracing
3.重新標記:Stop the world,修正併發標記期間,因使用者程式繼續執行導致標記產生變動的那一部分物件的標記記錄。
4.併發清除:併發清除可以和使用者執行緒一起執行,所以總體上停頓的時間非常短。
但是CMS收集器有三個顯著缺點:
1.對CPU資源敏感。
2.無法處理浮動垃圾。
3.收集結束後會產生大量碎片。

1.7G1(10ms) 演算法:三色標記 + SATB

  1.G1的設計原則是"首先收集儘可能多的垃圾(Garbage First)"。因此,G1並不會等記憶體耗盡(序列、並行)或者快耗盡(CMS)的時候開始垃圾收集,而是在內部採用了啟發式演算法,在老年代找出具有高收集收益的分割槽進行收集。同時G1可以根據使用者設定的暫停時間目標  自動調整年輕代和總堆大小,暫停目標越短年輕代空間越小、總空間就越大;
  2.G1採用記憶體分割槽(Region)的思路,將記憶體劃分為一個個相等大小的記憶體分割槽,回收時則以分割槽為單位進行回收,存活的物件複製到另一個空閒分割槽中。由於都是以相等大小的分割槽為單位進行操作,因此G1天然就是一種壓縮方案(區域性壓縮);
  3.G1雖然也是分代收集器,但整個記憶體分割槽不存在物理上的年輕代與老年代的區別,也不需要完全獨立的survivor(to space)堆做複製準備。G1只有邏輯上的分代概念,或者說每個分割槽都可能隨G1的執行在不同代之間前後切換;
  4.G1的收集都是STW的,但年輕代和老年代的收集界限比較模糊,採用了混合(mixed)收集的方式。即每次收集既可能只收集年輕代分割槽(年輕代收集),也可能在收集年輕代的同時,包含部分老年代分割槽(混合收集),這樣即使堆記憶體很大時,也可以限制收集範圍,從而   降低停頓。
  原文連結:https://blog.csdn.net/coderlius/article/details/79272773

1.8ZGC (1ms)PK C++ 演算法:ColoredPointers + LoadBarrier

1.9Shenandoah演算法:ColoredPointers + WriteBarrier

1.10Eplison

1.11PS 和 PN區別的延伸閱讀: ▪https://docs.oracle.com/en/java/javase/13/gctuning/ergonomics.html#GUID-3D0BB91E-9BFF-4EBB-B523-14493A860E73

2.垃圾收集器跟記憶體大小的關係

1.Serial 幾十兆

2.PS 上百兆 - 幾個G

3.CMS - 20G

4.G1 - 上百G

5.ZGC - 4T - 16T(JDK13)

1.8預設的垃圾回收:PS + ParallelOld

3.三色標記演算法

  1.用於CMS和G1垃圾回收器,發生在併發標記垃圾階段

  2.三色分別是:黑色(自身和成員變數均被標記完成),灰色(自身被標記,成員變數未被標記),白色(未被標記的物件)

  3.三色標記是在根可達演算法的基礎上實現的。找到物件被引用就將其標記,未被標記的是垃圾。

  4.漏標

  第一階段:A引用B,B引用C。A完全掃描標記黑色,B部分掃描標記灰色,C還未被掃描,標記白色

  

  第二階段:標記過程中,B到C的引用斷開,此時A到C添加了新的引用。

       因為A已經被標記為黑色(完全掃描),所以當再次標記的時候,C不會被標記。

        B已經不引用C,所以掃描灰色B的時候,也不會標記C。這種情況就是漏標

  

  5.漏標的解決辦法

  CMS:Incremental Update增量更新,關注引用的增加

    將黑色重新標記未灰色,下次重新掃描屬性

  G1:SATB snapshot at the beginning 關注引用的刪除

    講引用推到GC的堆疊。保證C會被再次掃描。

    

不積跬步,無以至千里 本文轉載自:https://www.cnblogs.com/farmersun/p/12398846.html