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.