CMS收集器中兩個致命的問題


CMS是一個很好的並發垃圾收集器,但是使用過程中會產生兩個重要的問題。

  • promotion failed 晉升失敗
  • concurrent mode failure 收集器無法處理浮動垃圾

promotion failed 晉升失敗原因

該問題發生在Minor GC過程中,Survivor Space放不下轉移的對象,老年代也放不下(promotion failed發生的時候老年代CMS還沒有機會進行回收,又放不下轉移到老年代的對象,下一步就會產生concurrent mode fialure,發生STW降級為Serial Old)

下面是一條promotion failed失敗的日志

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產生的原因

concurrent mode failureCMS特有的錯誤,CMS的垃圾清理線程和用戶線程是並行進行的. 老年代正在清理,從年輕代晉升了新對象,或者分配的大對象在新生代放不下,直接在老年代分配內存,這時老年代也放不下,則會拋出concurrent mode failure

concurrent mode failure的影響

老年代的垃圾收集器從CMS退化成Serial Old,所有用戶線程被暫停,停頓時間變長。

解決方案

CMS觸發太晚

-XX:CMSInitiatingOccupancyFraction=N 是指設定CMS在對內存占用率達到N%的時候開始GC(因為CMS會有浮動垃圾,所以一般都較早啟動GC);

  • 將:-XX:CMSInitiatingOccupancyFraction=N調小

空間碎片太多

開啟空間碎片整理,並將空間碎片整理周期設置在合理范圍,-XX:CMSFullGCsBeforeCompaction作用:設置在執行多少次Full GC后對內存空間進行壓縮整理。

  • -XX:+UseCMSCompactAtFullCollection (空間碎片整理)
  • -XX:CMSFullGCsBeforeCompaction=n

垃圾產生太快

  • 晉升閾值太小
  • Survivor空間過小
  • Eden區過小,導致晉升速率過快
  • 存在大對象


免責聲明!

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



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