Concurrent mark sweep (CMS) 收集器是一種年老代垃圾收集器,其最主要目標是獲取最短垃圾回收停頓時間,和其他年老代使用標記 - 整理算法不同,它使用多線程的標記 - 清除算法。
最短的垃圾收集停頓時間可以為交互比較高的程序提高用戶體驗,CMS 收集器是 Sun HotSpot 虛擬機中第一款真正意義上并發垃圾收集器,它第一次實現了讓垃圾收集線程和用戶線程同時工作。
CMS 工作機制相比其他的垃圾收集器來說更復雜,整個過程分為以下 4 個階段:
初始標記:只是標記一下 GC Roots 能直接關聯的對象,速度很快,仍然需要暫停所有的工作線程。
并發標記:進行 GC Roots 跟蹤的過程,和用戶線程一起工作,不需要暫停工作線程。
重新標記:為了修正在并發標記期間,因用戶程序繼續運行而導致標記產生變動的那一部分對象的標記記錄,仍然需要暫停所有的工作線程。
并發清除:清除 GC Roots 不可達對象,和用戶線程一起工作,不需要暫停工作線程。
由于耗時最長的并發標記和并發清除過程中,垃圾收集線程可以和用戶現在一起并發工作,所以總體上來看 CMS 收集器的內存回收和用戶線程是一起并發地執行。
CMS 收集器有以下三個不足:
CMS 收集器對 CPU 資源非常敏感,其默認啟動的收集線程數 =(CPU 數量 + 3)/4,在用戶程序本來 CPU 負荷已經比較高的情況下,如果還要分出 CPU 資源用來運行垃圾收集器線程,會使得 CPU 負載加重。
CMS 無法處理浮動垃圾 (Floating Garbage),可能會導致 Concurrent ModeFailure 失敗而導致另一次 Full GC。由于 CMS 收集器和用戶線程并發運行,因此在收集過程中不斷有新的垃圾產生,這些垃圾出現在標記過程之后,CMS 無法在本次收集中處理掉它們,只好等待下一次 GC 時再將其清理掉,這些垃圾就稱為浮動垃圾。
CMS 垃圾收集器不能像其他垃圾收集器那樣等待年老代機會完全被填滿之后再進行收集,需要預留一部分空間供并發收集時的使用,可以通過參數 - XX:CMSInitiatingOccupancyFraction 來設置年老代空間達到多少的百分比時觸發 CMS 進行垃圾收集,默認是 68%。
如果在 CMS 運行期間,預留的內存無法滿足程序需要,就會出現一次 ConcurrentMode Failure 失敗,此時虛擬機將啟動預備方案,使用 Serial Old 收集器重新進行年老代垃圾回收。
CMS 收集器是基于標記 - 清除算法,因此不可避免會產生大量不連續的內存碎片,如果無法找到一塊足夠大的連續內存存放對象時,將會觸發因此 Full GC。CMS 提供一個開關參數 - XX:+UseCMSCompactAtFullCollection,用于指定在 Full GC 之后進行內存整理,內存整理會使得垃圾收集停頓時間變長,CMS 提供了另外一個參數 - XX:CMSFullGCsBeforeCompaction,用于設置在執行多少次不壓縮的 Full GC 之后,跟著再來一次內存整理。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.