常見的垃圾回收器


常見的垃圾回收器:

    • Serial
    • Serial Old
    • Parallel Scavenge
    • Parallel Old
    • ParNew
    • CMS
    • G1
    • ZGC
    • Shenandoah
    • Epsilon

下圖已經列出來了這,其中Epsilon是debug使用的,不用過分關注;最常見的組合有:Serial +Serial Old 、Parallel Scavenge + Parallel Old 、ParNew + CMS。G1之前都是不僅在邏輯上是分代的而且在物理層面上也是分代的;G1只是在邏輯上分代;G1之后完全不分代,但是在生產環境使用的很少;

 1、Serial

當垃圾收集器工作時所有工作線程全部停止,這里線程停下來一定會停在一個安全點上;

safe-point :線程停止(需要找到一個安全點上線程停止),因為停頓的時間長,現在很少用;

 2、Serial Old 

這個垃圾收集器用在老年代,它用的是mark-sweep的算法,他用的是單線程;

a stop-the-world 

mark-sweep-compact  collector that uses a single GC thread(使用單個GC線程的標記-清理-收集器).

3、Parallel Scavenge

a stop-the-world 

Copying collector which uses multiple GC threads(使用多個GC線程的復制收集器).

 如果你在JVM沒有做任何的調優的話,默認使用的是:parallel scavenge +parallel old  簡稱(ps + po)

Parallel Scavenge 與Serial的區別:Parallel Scavenge 是多線程清理垃圾,后者為單線程清理垃圾。

4、Parallel Old 

a compacting collector that uses multiple GC threads(使用多個GC線程的壓縮收集器).

整理算法

5、ParNew

其實就是parallel new 的意思,和Parallel Scavenge沒有很大的區別,就是它的新版本,做了一些的增強以便能夠讓它和CMS有更好的配合使用,CMS在某個特定的階段會和Parallel New 同時運行。在工作的時候其余的線程不能夠工作,必須等GC回收器結束后才可以。

Parallel New 和 Parallel Scavenge 區別:

    • parallel new 的響應時間優先
    • 能夠配合CMS
    • parallel scavenge 的吞吐量優先

6、CMS

CMS非常重要,它誕生了一個里程碑,以前的垃圾回收器在工作的時候其他的線程都要停下來,等我工作完,才能工作,CMS的出現消除了這個問題,與此同時CMS也帶來了很多問題,以至於目前的所有的JDK版本默認都不是使用它。

    • CMS的全拼:concurrent mark sweep
    • A mostly concurrent , low-pause collector
    • Four phases: 
    1. initial mark (初始標記 STW開始標記)
    2. concurrent mark (並發標記和應用程序同時進行)
    3. remark (重新標記又是一個STW 在並發標記中產生的新垃圾 在這里進行重新標記 這里是使用多線程)
    4. concurrent sweep(並發清理的過程中也會產生新的垃圾 這個垃圾叫做浮動垃圾)

6.1、從線程角度理解:

垃圾回收器在工作的時候,垃圾回收的線程和工作線程同時進行,叫做:concurrent mark sweep;當內存比較小的情況下,清理垃圾的速度比較快沒有問題,當內存越來越大較的時候,大到什么程度呢?大到你用多少線程進行清理的都需要很長一段時間,以前10G的內存的時候使用默認的ps+po大概需要的時間為11s。

 為什么會出現並發垃圾回收器?  並發垃圾回收器出現的原因是因為忍受不了STW.

6.2、下面來解釋一下CMS常見的幾個階段:

第一個階段叫做CMS initial mark(初始標記階段)這個階段很簡單,就是直接找到最根上的對象,然后進行標記,其他的對象不標記。

第二個階段是CMS concurrent mark(並發標記)據統計百分之八十的時間都浪費在這里,因此它把這塊耗時最長的階段和我們的應用程序同時進行,對於客戶來說感覺上可能慢了點,但是至少還有反應,這里的並發標記是一邊產生垃圾一邊進行跟着標記,這個過程很難完成;

第三階段是CMS remark (重新標記)這里又是一個STW,在上一個並發標記的過程中產生的新垃圾在這個階段進行標記,這個時候需要停頓,但是時間不會很長,畢竟只是上一步很短時間內產生的新垃圾;

第四階段是concurrent sweep(並發清理)並發清理也有他的問題,在並發清理的過程中也會產生新的垃圾,這個垃圾叫做浮動垃圾,這個浮動垃圾就要等下一次CMS來清理了;

什么條件下會觸發CMS呢?老年代分配不下了,這時會觸發CMS,這里的初始標記是單線程,重新標記是多線程。

6.3、CMS的缺點:CMS出現問題后會調用Serial Old使用單線程進行標記壓縮;

 CMS的兩大問題:

memory fragmentation 內存的碎片:這個是比比較嚴重的一個問題,如果內存超級大,產生了很多的碎片,這就會浪費很多的空間,其實CMS設計出來就是應付幾百兆的內存至上G的內存,有的人拿它來應付很大內存就會出現問題,因為一旦老年代產生很多碎片,從新生代過來的對象就會出現找不到空間的情況,這叫做:PromotionFailed找不到空間。這時候它干了一件事情,把Serial Old 請出來,讓它用一個線程在這里進行標記壓縮。

floating garbage浮動垃圾:當出現Concurrent Mode Failure 和 PromotionFailed時,說明碎片較多,Old區內存分配不下,會調用Serial Old。並不是說使用了CMS之后這個問題沒辦法避免,可以降低觸發CMS的閾值。

解決方法降低CMS的閾值:  -XX:CMSInitiatingOccupancyFraction 92%  可以降低這個值,讓CMS保持老年代有足夠的空間。

Remark階段的算法:

怎么才能進行並發標記呢 非常的復雜,CMS采用的是三色標記+Incremental Update 算法。

      • 三色掃描算法:白灰黑
      • 在並發標記時,引用可能發生變化,白色對象有可能會被錯誤回收
      • 解決方法:SATB (snapshot at the beginning)     在起始的時候做一個快照    
      • Incremental Update  :  當一個白色對象被一個黑色對象引用時,將黑色對象重新標記為灰色,讓垃圾回收器重新掃描;

 

常見的垃圾回收器就介紹這么多,下一篇會給大家介紹一下 PS+PO;如果寫的有誤的地方還請大佬指出;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM