標籤:
當使用CMS收集器時,當開始進行收集時,old代的收集過程如下所示:
1,首先jvm根據-XX:CMSInitiatingOccupancyFraction,-XX:+UseCMSInitiatingOccupancyOnly來決定什麼時間開始垃圾收集;
2,如果設定了-XX:+UseCMSInitiatingOccupancyOnly,那麼只有當old代佔用確實達到了-XX:CMSInitiatingOccupancyFraction參數所設定的比例時才會觸發cms gc;
3,如果沒有設定-XX:+UseCMSInitiatingOccupancyOnly,那麼系統會根據統計資料自行決定什麼時候觸發cms gc;因此有時會遇到設定了80%比例才cms gc,但是50%時就已經觸發了,就是因為這個參數沒有設定的原因;
4,當cms gc開始時,首先的階段是CMS-initial-mark,此階段是初始標記階段,是stop the world階段,因此此階區段標記的對象只是從root集最直接可達的對象;
CMS-initial-mark:961330K(1572864K),指標記時,old代的已用空間和總空間
5,下一個階段是CMS-concurrent-mark,此階段是和應用線程並發執行的,所謂並發收集器指的就是這個,主要作用是標記可達的對象
此階段會列印2條日誌:CMS-concurrent-mark-start,CMS-concurrent-mark
6,下一個階段是CMS-concurrent-preclean,此階段主要是進行一些預清理,因為標記和應用線程是並發執行的,因此會有些對象的狀態在標記後會改變,此階段正是解決這個問題因為之後的Rescan階段也會stop the world,為了使暫停時間儘可能的小,也需要preclean階段先做一部分工作以節省時間
此階段會列印2條日誌:CMS-concurrent-preclean-start,CMS-concurrent-preclean
7,下一階段是CMS-concurrent-abortable-preclean階段,加入此階段的目的是使cms gc更加可控一些,作用也是執行一些預清理,以減少Rescan階段造成應用暫停時間
此階段涉及幾個參數:
-XX:CMSMaxAbortablePrecleanTime:當abortable-preclean階段執行達到這個時間時才會結束
-XX:CMSScheduleRemarkEdenSizeThreshold(預設2m):控制abortable-preclean階段什麼時候開始執行,
即當eden使用達到此值時,才會開始abortable-preclean階段
-XX:CMSScheduleRemarkEdenPenetratio(預設50%):控制abortable-preclean階段什麼時候結束執行
此階段會列印一些日誌如下:
CMS-concurrent-abortable-preclean-start,CMS-concurrent-abortable-preclean,
CMS:abort preclean due to time XXX
8,再下一個階段是第二個stop the world階段了,即Rescan階段,此階段暫停應用線程,對對象進行重新掃描並標記;
YG occupancy:964861K(2403008K),指執行時young代的情況
CMS remark:961330K(1572864K),指執行時old代的情況
此外,還列印出了弱引用處理、類卸載等過程的耗時
9,再下一個階段是CMS-concurrent-sweep,進行並發的垃圾清理
10,最後是CMS-concurrent-reset,為下一次cms gc重設相關資料結構
11,full gc:
有2種情況會觸發full gc,在full gc時,整個應用會暫停
A,concurrent-mode-failure:當cms gc正進行時,此時有新的對象要進行old代,但是old代空間不足造成的
B,promotion-failed:當進行young gc時,有部分young代對象仍然可用,但是S1或S2放不下,因此需要放到old代,但此時old代空間無法容納此。
影響cms gc時間長度及觸發的參數是以下2個:
-XX:CMSMaxAbortablePrecleanTime=5000
-XX:CMSInitiatingOccupancyFraction=80
解決也是針對這兩個參數來的,根本的原因是每次請求消耗的記憶體量過大
解決方式:
A,針對cms gc的觸發階段,調整-XX:CMSInitiatingOccupancyFraction=50,提早觸發cms gc,就可以緩解當old代達到80%,cms gc處理不完,從而造成concurrent mode failure引發full gc
B,修改-XX:CMSMaxAbortablePrecleanTime=500,縮小CMS-concurrent-abortable-preclean階段的時間
C,考慮到cms gc時不會進行compact,因此加入-XX:+UseCMSCompactAtFullCollection
(cms gc後會進行記憶體的compact)和-XX:CMSFullGCsBeforeCompaction=4(在full gc4次後會進行compact)參數
[轉]並發記憶體回收行程CMS介紹