CMS之promotion failed&concurrent mode failure

CMS并行GC收集器是大多數(shù)JAVA服務(wù)應(yīng)用的最佳選擇,然而隔盛, CMS并不是完美的,在使用CMS的過程中會產(chǎn)生2個最讓人頭痛的問題:

promotion failed

該問題是在進(jìn)行Minor GC時拾稳,Survivor Space放不下吮炕,對象只能放入老年代,而此時老年代也放不下造成的访得。(promotion failed時老年代CMS還沒有機(jī)會進(jìn)行回收龙亲,又放不下轉(zhuǎn)移到老年代的對象,因此會出現(xiàn)下一個問題concurrent mode failure悍抑,需要stop-the-wold 降級為GC-Serail Old)鳄炉。
下面是一個promotion failed的一條gc日志:

106.641: [GC 106.641: [ParNew (promotion failed): 14784K->14784K(14784K), 0.0370328 secs]106.678: [CMS106.715: [CMS-concurrent-mark: 0.065/0.103 secs] [Times: user=0.17 sys=0.00, real=0.11 secs]
(concurrent mode failure): 41568K->27787K(49152K), 0.2128504 secs] 52402K->27787K(63936K), [CMS Perm : 2086K->2086K(12288K)], 0.2499776 secs] [Times: user=0.28 sys=0.00, real=0.25 secs]

concurrent mode failure

該問題是在執(zhí)行CMS GC的過程中同時業(yè)務(wù)線程將對象放入老年代,而此時老年代空間不足搜骡,或者在做Minor GC的時候拂盯,新生代Survivor空間放不下,需要放入老年代记靡,而老年代也放不下而產(chǎn)生的谈竿。
下面是一個concurrent mode failure的一條gc日志:

0.195: [GC 0.195: [ParNew: 2986K->2986K(8128K), 0.0000083 secs]0.195: [CMS0.212: [CMS-concurrent-preclean: 0.011/0.031 secs] [Times: user=0.03 sys=0.02, real=0.03 secs]
(concurrent mode failure): 56046K->138K(57344K), 0.0271519 secs] 59032K->138K(65472K), [CMS Perm : 2079K->2078K(12288K)], 0.0273119 secs] [Times: user=0.03 sys=0.00, real=0.03 secs]

下面我們詳細(xì)的分析這兩個問題產(chǎn)生的原因以及如何進(jìn)行解決。

首先我們經(jīng)常遇到promotion failed問題摸吠,這也確實(shí)是個很頭痛的問題榕订,一般是進(jìn)行Minor GC的時候,發(fā)現(xiàn)Survivor空間不夠蜕便,所以劫恒,需要移動一些新生帶的對象到老年帶,然而轿腺,有些時候盡管老年代有足夠的空間两嘴,但是由于CMS采用標(biāo)記清除算法,默認(rèn)并不使用標(biāo)記整理算法族壳,可能會產(chǎn)生很多碎片憔辫,因此,這些碎片無法完成大對象向老年帶轉(zhuǎn)移仿荆,因此需要進(jìn)行CMS在老年帶的Full GC來合并碎片贰您。

這個問題的直接影響就是它會導(dǎo)致提前進(jìn)行CMS Full GC, 盡管這個時候CMS的老年代并沒有填滿坏平,只不過有過多的碎片而已,但是Full GC導(dǎo)致的stop-the-wold是難以接受的锦亦。

解決這個問題的辦法就是可以讓CMS在進(jìn)行一定次數(shù)的Full GC(標(biāo)記清除)的時候進(jìn)行一次標(biāo)記整理算法舶替,CMS提供了以下參數(shù)來控制:

-XX:UseCMSCompactAtFullCollection -XX:CMSFullGCBeforeCompaction=5
也就是CMS在進(jìn)行5次Full GC(標(biāo)記清除)之后進(jìn)行一次標(biāo)記整理算法,從而可以控制老年代的碎片在一定的數(shù)量以內(nèi)杠园,甚至可以配置CMS在每次Full GC的時候都進(jìn)行內(nèi)存的整理顾瞪。

另外,有些應(yīng)用存在比較大的對象朝生熄滅抛蚁,這些對象在救助空間無法容納陈醒,因此,會提早進(jìn)入老年代瞧甩,老年代如果有碎片钉跷,也會產(chǎn)生promotion failed, 因此我們應(yīng)該控制這樣的對象在新生代,然后在下次Minor GC的時候就被回收掉肚逸,這樣避免了過早的進(jìn)行CMS Full GC操作尘应,下面的一個配置樣例就通過增加Survivor空間的大小來解決這個問題:

-Xmx4000M -Xms4000M -Xmn600M -XXmSize=500M -XX:MaxPermSize=500M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=1 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled eCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log

上面討論了promotion failed引起的原因以及解決方案,除了promotion failed還有一個情況會引起CMS回收失敗吼虎,從而退回到Serial Old收集器進(jìn)行回收,我們在線上尤其要注意的是concurrent mode failure出現(xiàn)的頻率苍鲜,這可以通過-XX:+PrintGCDetails來觀察思灰,當(dāng)出現(xiàn)concurrent mode failure的現(xiàn)象時,就意味著此時JVM將繼續(xù)采用Stop-The-World的方式來進(jìn)行Full GC混滔,這種情況下洒疚,CMS就沒什么意義了,造成concurrent mode failure的原因是當(dāng)minor GC進(jìn)行時坯屿,1)舊生代所剩下的空間小于Eden區(qū)域+From區(qū)域的空間油湖,或者2)在CMS執(zhí)行老年代的回收時有業(yè)務(wù)線程試圖將大的對象放入老年代,導(dǎo)致CMS在老年代的回收慢于業(yè)務(wù)對象對老年代內(nèi)存的分配领跛。

解決這個問題的通用方法是調(diào)低觸發(fā)CMS GC執(zhí)行的閥值乏德,CMS GC觸發(fā)主要由CMSInitiatingOccupancyFraction值決定,默認(rèn)情況是當(dāng)舊生代已用空間為68%時吠昭,即觸發(fā)CMS GC喊括,在出現(xiàn)concurrent mode failure的情況下,可考慮調(diào)小這個值矢棚,提前CMS GC的觸發(fā)郑什,以保證舊生代有足夠的空間。

總結(jié):

  1. promotion failed – concurrent mode failure
    Minor GC后蒲肋, Survivor空間容納不了剩余對象蘑拯,將要放入老年代钝满,老年代有碎片或者不能容納這些對象,就產(chǎn)生了concurrent mode failure, 然后進(jìn)行stop-the-world的Serial Old收集器申窘。

解決辦法:-XX:UseCMSCompactAtFullCollection -XX:CMSFullGCBeforeCompaction=5 或者調(diào)大新生代或者Survivor空間

  1. concurrent mode failure

CMS是和業(yè)務(wù)線程并發(fā)運(yùn)行的弯蚜,在執(zhí)行CMS的過程中有業(yè)務(wù)對象需要在老年代直接分配,例如大對象偶洋,但是老年代沒有足夠的空間來分配熟吏,所以導(dǎo)致concurrent mode failure, 然后需要進(jìn)行stop-the-world的Serial Old收集器。

解決辦法:+XX:CMSInitiatingOccupancyFraction玄窝,調(diào)大老年帶的空間牵寺,+XX:CMSMaxAbortablePrecleanTime

總結(jié)一句話:使用標(biāo)記整理清除碎片和提早進(jìn)行CMS操作。

【轉(zhuǎn)自】https://my.oschina.net/hosee/blog/674181

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恩脂,一起剝皮案震驚了整個濱河市帽氓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌俩块,老刑警劉巖黎休,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異玉凯,居然都是意外死亡势腮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門漫仆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捎拯,“玉大人,你說我怎么就攤上這事盲厌∈鹫眨” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵吗浩,是天一觀的道長建芙。 經(jīng)常有香客問我,道長懂扼,這世上最難降的妖魔是什么禁荸? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮阀湿,結(jié)果婚禮上屡限,老公的妹妹穿的比我還像新娘。我一直安慰自己炕倘,他們只是感情好钧大,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著罩旋,像睡著了一般啊央。 火紅的嫁衣襯著肌膚如雪眶诈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天瓜饥,我揣著相機(jī)與錄音逝撬,去河邊找鬼。 笑死乓土,一個胖子當(dāng)著我的面吹牛宪潮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播趣苏,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼狡相,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了食磕?” 一聲冷哼從身側(cè)響起尽棕,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎彬伦,沒想到半個月后滔悉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡单绑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年回官,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搂橙。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡歉提,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出份氧,到底是詐尸還是另有隱情,我是刑警寧澤弯屈,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布蜗帜,位于F島的核電站,受9級特大地震影響资厉,放射性物質(zhì)發(fā)生泄漏厅缺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一宴偿、第九天 我趴在偏房一處隱蔽的房頂上張望湘捎。 院中可真熱鬧,春花似錦窄刘、人聲如沸窥妇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽活翩。三九已至烹骨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間材泄,已是汗流浹背沮焕。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拉宗,地道東北人峦树。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像旦事,于是被迫代替她去往敵國和親魁巩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 原文閱讀 前言 這段時間懈怠了族檬,罪過歪赢! 最近看到有同事也開始用上了微信公眾號寫博客了,挺好的~給他們點(diǎn)贊单料,這博客我...
    碼農(nóng)戲碼閱讀 5,968評論 2 31
  • 前言 最近斷斷續(xù)續(xù)看了《Java Performance The Definitive Guide》前六章埋凯,記錄一...
    LNAmp閱讀 1,090評論 0 0
  • JVM架構(gòu) 當(dāng)一個程序啟動之前,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū))扫尖,執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,664評論 0 7
  • System.gc整理 System.gc()源碼public static void gc() { Runtim...
    andersonoy閱讀 2,943評論 0 1
  • 0. 前言 JVM筆記系列白对,以JDK1.7為基準(zhǔn),主要以《深入理解Java虛擬機(jī)》(第二版)和《Java虛擬機(jī)規(guī)范...
    郭尋撫閱讀 910評論 0 3