jvm垃圾收集器你學廢了嗎(三)

前言

第一篇文章說了Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS(傳送門)這六種收集器,第二篇文章說了經典的G1收集器(傳送門),今天我們還要單獨的說一下低延遲收集器Shenandoah,Shenandoah收集器是一款只有OpenJDk纔會包含的,這時候問題來了 什麼是OpenJDK和OracleJDk呢?
OpenJDK是JDK的開放源碼版本,在JDK11之後兩者幾乎一致,這篇文章寫得比較清楚OpenJDK和OracleJDK的區別
在這裏插入圖片描述

Shenandoah與G1收集器比較
  • Shenandoah和G1都採用相同的內存佈局
  • 默認的回收策略也一樣,都是優先回收價值最大的Region
  • Shenandoah摒棄了G1中耗費大量內存和計算資源去維護的記憶集
    Shenandoah採用的是“連接矩陣”,連接矩陣是一個來記錄跨Region的引用關係。可以理解爲一張二維表
  • 連接矩陣降低了處理跨代指針時的記憶集維護消耗
  • 在回收階段G1收集器不能與用戶線程併發,而Shenandoah則可以和用戶線程併發

Shenandoah收集器的工作過程

Shenandoah的工作過程可分爲9步,但是這9步有和G1相似的地方我就不多闡述了,可以看我上一篇博客詳細說了G1收集器

  • 初始標記
    和G1一樣,標記GC Roots ,同樣也是 Stop The World
  • 併發標記
    和G1一樣,標記處所有可達對象,這個階段可與用戶線程併發執行
  • 最終標記
    和G1一樣,處理剩餘的SATB(原始快照)
  • 併發清理
    這個階段是處理那些整個區域沒有一個存活對象的Region
  • 併發回收
    先把存活的對象移動到另一個Region區域中,但是這個過程是和用戶線程併發的,就是出現用戶線程訪問舊對象地址的情況,Shenandoah用讀屏障和“Brooks Pointers”的轉發指針來解決,
    什麼是讀屏障:寫屏障是對象的引用發生變化是會記錄下來,讀屏障就是讀出這個地址
    什麼是轉發指針(Brooks是一個人名):當用戶程序訪問到舊對象的內存空間就會產生自陷中斷,進入事先設定好的異常處理中,然後在轉發的新的地址
  • 初始引用更新
    這個階段沒有把所有指向舊對象的引用修正爲對象的新地址,而是僅僅確保併發回收階段的收集線程都已經完成了任務,這個階段需要非常短的停頓時間
  • 併發引用更新
    真正引用更新是這這個階段,這個階段是和用戶線程併發執行的。
  • 最終引用更新
    這個階段修正存在與GC Roots中的引用,也需要短暫的停頓時間
  • 併發清理
    回收這些標記的Region空間,供以後新對象分配使用

其實上面9個步驟中,最重要的就是併發標記、併發回收、併發引用更新 這三個階段
在這裏插入圖片描述

總結

Shenandoah收集器作爲第一款由非Oracle開發的垃圾收集器,表現出如此好的性能,基本上全部的工作過程都是併發的,初始標記和最終標記的停頓時間基本上是固定的,與堆的容量和堆中對象的數量沒有正比例的關係!
看到這裏, 你學廢了嗎?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章