為什麼CMS要為老年代預留空間?

紳士jiejie發表於2020-10-14

CMS在最後一個併發清理階段才會真正的開始清理垃圾物件,不過這些垃圾物件都是在回收之前標記好的垃圾物件,該階段也是使用者執行緒和垃圾回收執行緒併發執行的,所以在這個階段,系統也是在一直執行的,此時很有可能會有物件需要進入老年代,所以一邊的CMS在回收垃圾物件,另一邊又不斷放入物件,如果記憶體不夠了,就會觸發Concurrent Mode Failure,代表著併發垃圾回收失敗了,接著就會自動切換成“Serial Old”垃圾回收器替代CMS,強行把系統程式“Stop the World”,重新進行長時間的GC Roots追蹤,標記出全部的垃圾物件,直到全部垃圾物件被回收完成後再恢復系統執行,相對來說,“Serial Old”垃圾回收器的耗時是比較長的,所以要儘量避免出現“Serial Old”垃圾回收器替代CMS的情況,也就是要儘量避免出現Concurrent Mode Failure問題,那麼就要保證在CMS併發清理階段,預留足夠的空間讓一些物件可以進入老年代。

該預留空間可以通過引數-XX:+CMSInitiatingOccupancyFraction引數來設定,JDK1.6裡預設值是92%,表示在老年代空間被使用92%後就自動觸發CMS垃圾回收,剩下的8%就是預留空間,方便在併發回收期間,讓一些物件順利進入老年代,不會觸發Concurrent Mode Failure問題。

相關文章