CMS垃圾收集器深入詳解


上一次【https://www.cnblogs.com/webor2006/p/11048407.html】對安全點和安全區進行了理論化的了解,接下來繼續對CMS進行其它理論的了解,還是純理論!!堅持,因為下一次就會有實踐代碼了~~

CMS收集器

  • CMS(Concurrent Mark Sweep)收集器,以獲取最短回收停頓時間【也就是指Stop The World的停頓時間】為目標,多數應用於互聯網站或者B/S系統的服務器端上。其中“Concurrent”並發是指垃圾收集的線程和用戶執行的線程是可以同時執行的。
  • CMS是基於“標記-清除”算法實現的,整個過程分為4個步驟:
    1、初始標記(CMS initial mark)。
    2、並發標記(CMS concurrent mark)。
    3、重新標記(CMS remark)。
    4、並發清除(CMS concurrent sweep)。
    注意:“標記”是指將存活的對象和要回收的對象都給標記出來,而“清除”是指清除掉將要回收的對象。
  • 其中,初始標記、重新標記這兩個步驟仍然需要“Stop The World”。
  • 初始標記只是標記一下GC Roots能直接關聯到的對象,速度很快。
  • 並發標記階段【也就說明不會阻礙業務線程繼續執行,因為它所以還會有下面要說的“重新標記”階段了】就是進行GC Roots Tracing【啥意思?其實就是從GC Roots開始找到它能引用的所有其它對象】的過程。
  • 重新標記階段則是為了修正並發標記期間因用戶程序繼續動作而導致標記產生變動的那一部分對象的標記記錄,這個階段的停頓時間一般會比初始標記階段稍長一些,但遠比並發標記的時間短。
  • CMS收集器的動作步驟如下圖所示,在整個過程中耗時最長的並發標記和並發清除過程收集器線程都可以與用戶線程一起工作,因此,從總體上看,CMS收集器的內存回收過程是與用戶線程一起並發執行的:

    下面對這個圖做一個簡要的解讀:

    這個“重置線程"並沒有體現在之前的4個步驟當中,這個在之后會說的,對於這張圖的理解可以很好的理解CMS的幾個步驟。 

  • 優點:並發收集、低停頓【注意:這里的停頓指的是停止用戶線程】,Oracle公司的一些官方文檔中也稱之為並發低停頓收集器(Concurrent Low Pause Collector)。
  • 缺點:
    1、CMS收集器對CPU資源非常敏感。
    2、CMS收集器無法處理浮動垃圾(Floating Garbage,就是指在之前判斷該對象不是垃圾,由於用戶線程同時也是在運行過程中的,所以會導致判斷不准確的, 可能在判斷完成之后在清除之前這個對像已經變成了垃圾對象,所以有可能本該此垃圾被回收但是沒有被回收,只能等待下一次GC再將該對象回收,所以這種對像就是浮動垃圾),可能出現“Concurrent Mode Failure”失敗而導致另一次Full GC的產生。如果在應用中老年代增長不是太快,可能適當調高參數-XX:CMSInitiatingOccupancyFraction的值來提高觸發百分比,以便降低內存回收次數從而獲取更好的性能。要是CMS運行期間預留的內存無法滿足程序需要時,虛擬機將啟動后備預案:臨時啟用Serial Old收集器來重新進行老年代的垃圾收集,這樣停頓時間就很長了。所以說參數-XX:CMSInitiatingOccupancyFraction設置得太高很容易導致大量“Concurrent Mode Failure”失敗,性能反而降低。
    3、收集結束時會有大量空間碎片產生,空間碎片過多時,將會給大對象分配帶來很大麻煩,往往出現老年代還有很大空間剩余,但是無法找到足夠大的連續空間來分配當前對象,不得不提前進行一次Full GC。CMS收集器提供了一個-XX:+UseCMSCompactAtFullCollection開關參數(默認就是開啟的),用於在CMS收集器頂不住要進行Full GC時開啟內存碎片的合並整理過程,內存整理的過程是無法並發的,空間碎片問題沒有了,但停頓時間不得不變長。

空間分配擔保:

在發生Minor GC之前,虛擬機會先檢查老年代最大可用的連續空間是否大於新生代所有對象總空間,如果這個條件成立,那么Minor GC可以確保是安全的。當大量對象在Minor GC后仍然存活,就需要老年代進行空間分配擔保,把Survivor無法容納的對象直接進入老年代。如果老年代判斷到剩余空間不足(根據以往每一次回收晉升到老年代對象空間的平均值作為經驗值),則進行一次Full GC。

 

CMS收集器收集完整步驟:

  • Phase1 :Initial Mark【初始標記】
  • Phase2 : Concurrent Mark 【並發標記】
  • Phase3 : Concurrent Preclean【並發預先清除】
  • Phase4 : Concurrent Abortable Preclean【並發可能失敗的預先清除】
  • Phase5 : Final Remark【最終重新標記】
  • Phase6 : Concurrent Sweep【並發清除】
  • Phase7 : Concurrent Reset【並發重置】

以上這些過程在下次會詳細進行學習,先有個了解。


免責聲明!

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



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