1. 程式人生 > >Java之CMS GC的7個階段

Java之CMS GC的7個階段

CMS收集器的主要設計目標是:低應用停頓時間。它通過兩種方式實現這一目標:

  1. 不壓縮老年代,而是使用空閒列表來管理回收空間。
  2. 大部分標記清理工作與應用程式併發執行。

主要問題:由於不壓縮帶來的老年代堆碎片,或者在物件分配率高的情況下,都可能導致Full GC。

CMS收集器的GC週期主要由7個階段組成,其中有兩個階段會發生stop-the-world,其他階段都是併發執行的。(亦有4個階段、6個階段等說法)

Phase 1: Initial Mark(初始化標記)

初始化標記階段,是CMS GC的第一個階段,也是標記階段的開始。主要工作是標記可直達的存活物件

主要標記過程

  • 從GC Roots遍歷可直達的老年代物件;
  • 遍歷被新生代存活物件所引用的老年代物件。

程式執行情況

  • 支援單執行緒或並行標記。
  • 發生stop-the-world,暫停所有應用執行緒。



 

(Marked obj:老年代綠色圓點表示被初始化標記的物件。)

Phase 2: Concurrent Mark(併發標記)

併發標記階段,是CMS GC的第二個階段。

在該階段,GC執行緒和應用執行緒將併發執行。也就是說,在第一個階段(Initial Mark)被暫停的應用執行緒將恢復執行。

併發標記階段的主要工作是,通過遍歷第一個階段(Initial Mark)標記出來的存活物件,繼續遞迴遍歷老年代,並標記可直接或間接到達的所有老年代存活物件



 

(Current obj:該物件的引用關係發生變化,對下一個物件的引用被刪除。)

由於在併發標記階段,應用執行緒和GC執行緒是併發執行的,因此可能產生新的物件或物件關係發生變化,例如:

  • 新生代的物件晉升到老年代;
  • 直接在老年代分配物件;
  • 老年代物件的引用關係發生變更;
  • 等等。

對於這些物件,需要重新標記以防止被遺漏。為了提高重新標記的效率,本階段會把這些發生變化的物件所在的Card標識為Dirty,這樣後續就只需要掃描這些Dirty Card的物件,從而避免掃描整個老年代。

Phase 3: Concurrent Preclean(併發預清理)

在併發預清洗階段,將會重新掃描前一個階段標記的Dirty物件,並標記被Dirty物件直接或間接引用的物件,然後清除Card標識

標記被Dirty物件直接或間接引用的物件:



 

清除Dirty物件的Card標識:



 

Phase 4: Concurrent Abortable Preclean(可中止的併發預清理)

本階段儘可能承擔更多的併發預處理工作,從而減輕在Final Remark階段的stop-the-world

在該階段,主要迴圈的做兩件事:

  • 處理 From 和 To 區的物件,標記可達的老年代物件;
  • 和上一個階段一樣,掃描處理Dirty Card中的物件。

具體執行多久,取決於許多因素,滿足其中一個條件將會中止執行:

  • 執行迴圈次數達到了閾值;
  • 執行時間達到了閾值;
  • 新生代Eden區的記憶體使用率達到了閾值。

Phase 5: Final Remark(重新標記)

預清理階段也是併發執行的,並不一定是所有存活物件都會被標記,因為在併發標記的過程中物件及其引用關係還在不斷變化中。

因此,需要有一個stop-the-world的階段來完成最後的標記工作,這就是重新標記階段(CMS標記階段的最後一個階段)。主要目的是重新掃描之前併發處理階段的所有殘留更新物件

主要工作:

  • 遍歷新生代物件,重新標記;(新生代會被分塊,多執行緒掃描)
  • 根據GC Roots,重新標記;
  • 遍歷老年代的Dirty Card,重新標記。這裡的Dirty Card,大部分已經在Preclean階段被處理過了。

Phase 6: Concurrent Sweep(併發清理)

併發清理階段,主要工作是清理所有未被標記的死亡物件,回收被佔用的空間



 

Phase 7: Concurrent Reset(併發重置)

併發重置階段,將清理並恢復在CMS GC過程中的各種狀態,重新初始化CMS相關資料結構,為下一個垃圾收集週期做好準備。

 

參考

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html#concurrent_mark_sweep_cms_collector

https://blogs.oracle.com/poonam/understanding-cms-gc-logs

https://blogs.oracle.com/jonthecollector/the-unspoken-phases-of-cms

https://plumbr.io/handbook/garbage-collection-algorithms-implementations#concurrent-mark-and-sweep

https://www.jianshu.com/p/2a1b2f17d3e4

http://psy-lob-saw.blogspot.com/2014/10/the-jvm-write-barrier-card-marking.html

https://www.cnblogs.com/littleLord/p/5380624.html

 

轉載請註明來源:https://zhanjia.iteye.com/blog/2435266

 

個人公眾號

更多文章,請關注公眾號:二進位制之路