CMS存在的問題

CMS存在的問題

概述

CMS 是老年代垃圾回收算法,通過標記-清除的方式,=意在通過并發(fā)的方式適度減少吞吐量,減少用戶線程停頓時間。

CMS收集器對處理器資源非常敏感

CMS的在垃圾清除是使用并發(fā)清除的,如果處理器核數(shù)不高的情況下,垃圾回收會造成很高的負載。

并發(fā)回收造成的內(nèi)存不足

造成原因

在CMS的并發(fā)標記和并發(fā)清理階段,用戶線程是還在繼續(xù)運行的,程序在運行自然就還會伴隨有新的垃圾對象不斷產(chǎn)生,而這部分的垃圾對象是出現(xiàn)在標記過程結(jié)束以后,CMS無法在當次收集中處理掉它們,只好留在下次垃圾收集時再清理掉。這樣的垃圾就叫做浮動垃圾。由于垃圾收集和用戶線程是并發(fā)執(zhí)行的,因此CMS收集器不能像其他收集器那樣幾乎填滿了再進行收集,需要預留一些空間用來保存用戶新創(chuàng)建的對象。

如何處理

在JDK1.5之前老年帶使用了68%空間后就會激活CMS收集。
如果實際應用中可以適當調(diào)整參數(shù)-XX:CMSInitiatingOccu-pancyFraction 的值來提高CMS的觸發(fā)百分比,降低內(nèi)存回收頻率獲得更好的性能。
到了JDK6 CMS收集器的啟動閥值就已經(jīng)默認提升到92%。

存在問題

如果預留空間不夠怎么辦?
首先要確定這是個小概率事件,其次JVM對著的情況處理如下:

  • CMS垃圾回收報錯(Concurrent Model Failure) 并發(fā)失敗。
  • 啟動后備預案:凍結(jié)用戶線程的執(zhí)行,臨時啟用Serial Old收集器來重新進行老年代的垃圾收集。(這樣的話時間就會變得很長)

內(nèi)存碎片問題

由于CMS老年代使用標記-清除回收策略,因此會有內(nèi)存碎片問題。當碎片過多時,將會給大對象分配帶來麻煩,往往會出現(xiàn)老年代還有很多空間但就已經(jīng)不能保存對象了。不得不提前觸發(fā)一次Full GC。為了解決這個問題,CMS收集器提供了-XX:UseCMSCompactAtFullCollection開關(guān)參數(shù),用于在CMS收集器不得不進行Full GC時開啟內(nèi)存碎片的合并整理過程。 有參數(shù)可以配置有多少次Full GC會堆內(nèi)存碎片進行整理(-XX:CMSFullGCsBeforeCompaction)

參考:深入理解java虛擬機 - 第三版

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容