天天看點

JVM垃圾收集器(三)JVM垃圾收集器(三)

JVM垃圾收集器(三)

垃圾回收(GC)線程與應用線程保持相對獨立,當系統需要執行垃圾回收任務時,先停止工作線程,然後指令GC線程工作,以串行模式工作的收集器,稱為Serial Collector,即串行收集器;與之相對的是以并行模式工作的收集器,稱為Paraller Collector,即并行收集器。

并行收集:指多條垃圾收集線程并行工作,但此時使用者線程仍處于等待狀态。

并發收集:指使用者線程與垃圾收集線程同時工作(不一定是并行的,會交替執行)。使用者程式在繼續運作,而垃圾收集程式運作在另一個CPU上。

吞吐量:即CPU用于運作使用者代碼的時間與CPU總消耗時間的比值,當虛拟機運作100分鐘,其中垃圾收集花掉1分鐘,那麼吞吐量就是99%。

垃圾收集器

  1. Serial收集器

    Serial收集器是最基本的、發展曆史最悠久的收集器。

    單線程、與其他收集器的單線程相比簡單高效,Serial是針對新生代的垃圾收集器采用**”複制“**算法,對于限定單個CPU的環境來說,Serial收集器沒有線程互動的開銷。收集器進行垃圾回收時,必須暫停其他所有的工作線程,直到它結束(Stop The World)。stop-the-world暫停時間的長短是衡量一款收集器性能高低的重要名額。

    JVM垃圾收集器(三)JVM垃圾收集器(三)
  2. ParNew收集器

    并行收集器充分利用多處理器的優勢,采用多個GC線程并行收集,顯然比隻使用一條GC線程執行的效率更高,在多處理器環境下工作的并行收集器可以極大的縮短Stop-The-World的時間。ParNew是針對新生代的垃圾收集器,采用“複制“算法,可以看做是Serial的多線程版本。

    JVM垃圾收集器(三)JVM垃圾收集器(三)
  3. Parallel Scavenge收集器

    Parallel Scavenge收集器和ParNew收集器類似,但更注重吞吐率,在ParNew的基礎上演化而來的,故也被稱為“吞吐量優先”收集器,吞吐量就是CPU運作使用者代碼的時間與CPU總消耗的時間的比值。

    采用“複制”算法。

    JVM垃圾收集器(三)JVM垃圾收集器(三)
  4. Serial Old收集器

    Serial Old是Serial收集器的老年代版本,同樣是單線程收集器采用“标記整理”算法,這個收集器是給Client模式下的虛拟機使用。

  5. Parallel Old收集器

    Parallel Old是Parallel Scanvenge收集器的老年代版本,多線程收集器,采用**“标記整理”**算法。

  6. CMS收集器

    CMS(Concurrent Mark Swee)收集器是一種以擷取最短回收停頓時間為目标的收集器。CMS收集器僅作用于老年代的收集,采用“标記清除”算法,它的運作過程分為4個步驟:

    • 初始标記(CMS initial mark)
    • 并發标記(CMS concurrent mark)
    • 重新标記(CMS remark)
    • 并發清除(CMS concurrent sweep)

    初始标記和中心标記這兩個步驟仍然需要Stop-The-World。初始标記僅僅隻是标記一下GCRoots能直接關聯到的對象,速度很快,并發标記階段就是進行GC Roots Tracing的過程,而重新标記階段則是為了修正并發标記期間因使用者程式繼續運作而導緻标記産生變動的那一部分對象的标記記錄,這個階段的停頓時間一般會比初始标記稍長一些,但遠比并發标記時間短。

    CMS收集器優點:并發收集,低停頓。

    CMS收集器缺點:使用标記清除算法,具有該算法的缺點。

    CMS收集器的記憶體回收過程是與使用者線程一起并發執行的。

    JVM垃圾收集器(三)JVM垃圾收集器(三)
  7. G1收集器

    G1收集器是面向服務端的垃圾收集器,在2004年發表論文,在JDK9成為了預設的服務端的垃圾收集器,替換掉了JDK5釋出的CMS收集器。

    G1收集器之前的所有的收集器,包括CMS在内垃圾收集的範圍要麼是整個新生代(Minor GC)、要麼就是整個老年代(Major GC)、要麼就是真個Java堆(Full GC),而G1則是面向堆記憶體任何部分來組成回收集進行回收,它是看那塊記憶體中存放的垃圾數量最多回收收益最大,這就是G1收集器的Mixed GC模式。

    G1把堆劃分為多個大小相等的獨立區域(Region),新生代和老年代不在實體隔離。通過引入Region的概念,進而将原來的一整塊記憶體空間劃分為多個的小空間,使得每個小空間可以單獨進行垃圾回收。這種劃分方式使得可預測的停頓時間成為可能。通過記錄每個Region垃圾回收時間以及回收所獲得的空間(這兩個值是通過過去回收的經驗獲得),并維護一個優先清單,每次根據允許的收集時間,優先回收價值最大的Region。

    每個Region都有一個Remember Set,用來記錄該Region對象的引用對象所在的Region。通過使用Remember Set,可以避免在做可達性分析的時候進行全堆掃描。

    JVM垃圾收集器(三)JVM垃圾收集器(三)
    G1收集器的運作過程大緻可以分為以下幾個步驟:
    • 初始标記:隻是标記一下GC Roots能直接關聯到的對象,這個階段需要停頓使用者線程,但耗時很短。
    • 并發标記:從GC Roots開始對堆進行可達性分析,遞歸掃描整個堆裡的對象圖,找出要回收的對象,這個階段耗時很長,但是與使用者線程并發執行。當對象圖掃描完成之後,還要重新處理STAB記錄下的在并發時有引用變動的對象。
    • 最終标記:對使用者線程做一個短暫的暫停,用于處理在并發階段遺留下來的少量的STAB記錄。
    • 篩選回收:負責更新Region的統計資料,對各個Region的回收價值和成本進行排序根據使用者所期望的GC停頓時間來制定回收計劃。這階段其實可以做到與使用者程式一起并發執行,因為隻回收一部分的Region,時間可控制,而且停頓使用者線程将大幅度提高收集效率。