如何選擇JVM垃圾回收器?

明確垃圾回收器組合

-XX:+UseSerialGC 年輕代和老年代都用串行收集器
-XX:+UseParNewGC 年輕代使用ParNew,老年代使用 Serial Old
-XX:+UseParallelGC 年輕代使用Paraller Scavenge,老年代使用Serial Old
-XX:+UseParallelOldGC 新生代Paraller Scavenge,老年代使用Paraller Old
-XX:+UseConcMarkSweepGC,表示年輕代使用ParNew,老年代的用CMS + Serial Old
-XX:+UseG1GC 使用G1垃圾回收器
-XX:+UseZGC 使用ZGC垃圾回收器

垃圾收集器跟內(nèi)存大小的大致關(guān)系(不精確,需要根據(jù)實際環(huán)境測試)

Serial:幾十兆
PS:上百兆 ~ 4G
CMS:4G ~ 10G
G1:10G~上百G
ZGC: 4T - 16T(JDK13)

常見的垃圾回收器

JDK誕生 Serial追隨 提高效率,誕生了PS,為了配合CMS,誕生了PN,CMS是1.4版本后期引入,CMS是里程碑式的GC,它開啟了并發(fā)回收的過程,但是CMS毛病較多,因此目前任何一個JDK版本默認是CMS 并發(fā)垃圾回收是因為無法忍受STW

  • Serial 年輕代 串行回收
  • PS 年輕代 并行回收
  • ParNew 年輕代 配合CMS的并行回收
  • SerialOld
  • ParallelOld
  • ConcurrentMarkSweep 老年代并發(fā)的,垃圾回收和應用程序同時運行,降低STW(Stop the World)的時間(200ms)。CMS問題比較多,所以現(xiàn)在沒有一個版本默認是CMS,只能手工指定 CMS既然是MarkSweep,就一定會有碎片化的問題,碎片到達一定程度,CMS的老年代分配對象分配不下的時候,使用SerialOld 進行老年代回收。
  • G1(10ms) 算法:三色標記 + SATB
  • ZGC (1ms) PK C++ 算法:ColoredPointers + LoadBarrier
  • Shenandoah 算法:ColoredPointers + WriteBarrier
  • Eplison

常見垃圾回收器組合參數(shù)設(shè)定:(1.8)

  • -XX:+UseSerialGC = Serial New (DefNew) + Serial Old
    小型程序。默認情況下不會是這種選項,HotSpot會根據(jù)計算及配置和JDK版本自動選擇收集器
  • -XX:+UseParNewGC = ParNew + SerialOld這個組合已經(jīng)很少用(在某些版本中已經(jīng)廢棄)
  • -XX:+UseConc(urrent)MarkSweepGC = ParNew + CMS + Serial Old
  • -XX:+UseParallelGC = Parallel Scavenge + Parallel Old (1.8默認) 【PS + SerialOld】
  • -XX:+UseParallelOldGC = Parallel Scavenge + Parallel Old
  • -XX:+UseG1GC = G1

默認GC的查看方法

  1. java -XX:+PrintCommandLineFlags -version
  2. 通過GC的日志來分辨

Linux下1.8版本默認的垃圾回收器到底是什么?
1.8.0_181 默認(看不出來)Copy MarkCompact
1.8.0_222 默認 PS + PO

面對如此眾多的垃圾回收器,我們應該如何選擇一款適合自己應用的收集器呢?這個問題的答案主要受以下三個因素影響:

  1. 應用程序的主要關(guān)注點是什么?
    a. 數(shù)據(jù)分析、科學計算類的任務,目標是能盡快算出結(jié)果,那吞吐量就是主要關(guān)注點;
    b. SLA 應用,那停頓時間直接影響服務質(zhì)量,嚴重的甚至會導致事務超時,這樣延遲就是主要關(guān)注點;
    c. 客戶端應用或者嵌入式應用,那垃圾收集的內(nèi)存占用則是不可忽視的。

  2. 運行應用的基礎(chǔ)設(shè)施如何?
    譬如硬件規(guī)格,要涉及的系統(tǒng)架構(gòu)是 x86-32/64、SPARC 還是ARM/Aarch64;處理器的數(shù)量多少,分配內(nèi)存的大小;選擇的操作系統(tǒng)是 Linux、Solaris 還是 Windows等。

  3. 使用 JDK 的發(fā)行商是什么?
    版本號是多少?是 ZingJDK/Zulu、OracleJDK、Open-JDK、OpenJ9 抑或是其他公司的發(fā)行版?該 JDK 對應了《Java 虛擬機規(guī)范》的哪個版本?

CMS存在的問題

  1. CMS收集器對處理器資源非常敏感
    CMS的在垃圾清除是使用并發(fā)清除的,如果處理器核數(shù)不高的情況下,垃圾回收會造成很高的負載。

  2. 并發(fā)回收造成的內(nèi)存不足
    2.1 造成原因(浮動垃圾)
    在CMS的并發(fā)標記和并發(fā)清理階段,用戶線程是還在繼續(xù)運行的,程序在運行自然就還會伴隨有新的垃圾對象不斷產(chǎn)生,而這部分的垃圾對象是出現(xiàn)在標記過程結(jié)束以后,CMS無法在當次收集中處理掉它們,只好留在下次垃圾收集時再清理掉。這樣的垃圾就叫做浮動垃圾。由于垃圾收集和用戶線程是并發(fā)執(zhí)行的,因此CMS收集器不能像其他收集器那樣幾乎填滿了再進行收集,需要預留一些空間用來保存用戶新創(chuàng)建的對象。
    2.2. 如何處理
    在JDK1.5之前老年帶使用了68%空間后就會激活CMS收集。
    如果實際應用中可以適當調(diào)整參數(shù)-XX:CMSInitiatingOccu-pancyFraction 的值來提高CMS的觸發(fā)百分比,降低內(nèi)存回收頻率獲得更好的性能。
    到了JDK6 CMS收集器的啟動閥值就已經(jīng)默認提升到92%。
    2.3 存在問題
    如果預留空間不夠怎么辦?
    首先要確定這是個小概率事件,其次JVM對著的情況處理如下:

CMS垃圾回收報錯(Concurrent Model Failure) 并發(fā)失敗。
啟動后備預案:凍結(jié)用戶線程的執(zhí)行,臨時啟用Serial Old收集器來重新進行老年代的垃圾收集。(這樣的話時間就會變得很長)

  1. 內(nèi)存碎片問題
    由于CMS老年代使用標記-清除回收策略,因此會有內(nèi)存碎片問題。當碎片過多時,將會給大對象分配帶來麻煩,往往會出現(xiàn)老年代還有很多空間但就已經(jīng)不能保存對象了。不得不提前觸發(fā)一次Full GC。為了解決這個問題,CMS收集器提供了-XX:UseCMSCompactAtFullCollection開關(guān)參數(shù),用于在CMS收集器不得不進行Full GC時開啟內(nèi)存碎片的合并整理過程。 有參數(shù)可以配置有多少次Full GC會堆內(nèi)存碎片進行整理(-XX:CMSFullGCsBeforeCompaction)

G1

G1打破了以往將收集范圍固定在新生代或老年代的模式,GI 將 Java 堆空間分割成了若干相同大小的 區(qū)域,即 region,包括 Eden、
Survivor、 Old、 Humongous 四種類型。其中, Humongous 是特殊的 Old 類型,專門 放置大型對象。這樣的劃分方式意昧著不需要一個連續(xù)的內(nèi)存空間管理對象。 GI 將空間分為多個區(qū)域,優(yōu)先回收垃圾最多的區(qū)域。 GI 采用的是好的空間整合能力’不會產(chǎn)生大量的空間碎片。

Region的數(shù)值是在1M到32M字節(jié)之間的一個2的冪值數(shù),JVM會盡量劃分2048個左右、同等大小的Region。

GI 的一大優(yōu)勢在于可預測的停頓時間, 能夠盡可能快地在指定時間內(nèi)完成垃圾回收任務。在 JDKl l 中,已經(jīng)將 GI 設(shè)為默認 垃圾回收器。

ZGC

和G1類似,但ZGC的region的大小更加靈活和動態(tài)。zgc的region不會像G1那樣在一開始就被劃分為固定大小的region。

zgc的region核心亮點就是:動態(tài)

動態(tài)表現(xiàn)為:

  • 動態(tài)地創(chuàng)建和銷毀。
  • 動態(tài)地決定region的大小。它的最小單位是2MB的一個塊。然后每個region的大小就是是2MB*N就是。

而且他有個概念叫:size groups。有三種:

  1. Small:就是一個2MB的region。
  2. Medium:32mb。2MB*16。
  3. Large:N*2MB。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容