JVM垃圾收集器的CMS回收流程及优缺点
今天介绍CMS垃圾回收器。 首先,CMS是多线程分段操作的垃圾回收。 最大的优点是,一次完整的回收过程可以划分为多个步骤,并在运行时继续用户线程。 也就是说,CMS减少STW的时间对我们的用户体验非常好,所以CMS垃圾回收器也是目前大多数企业使用最多的垃圾回收器。 (CMS只管老年) )。
接下来就CMS垃圾回收器从浅到深进行说明!
一、CMS垃圾收集器的使用和执行流程
使用CMS垃圾收集器很容易。 只需在JVM启动参数中添加一个
-XX: UseConcMarkSweeoGC
可以让JVM使用CMS作为老一代垃圾管理器。
接下来是我们的CMS运行过程。 把图放在下面
粉红色表示用户线程,黄色表示CMS线程
在此插入图像说明
在上图中,您可以看到在CMS回收中执行垃圾回收时,除了用户线程之外,已经执行了五个步骤。 它们分别有初始标签、并发标签、重新标签、并发清理和并发复位。 他们从什么意义上分别做了什么呢? 请不要着急。 接下来说明各步骤之间所做的事情
1 .初始标记:
初始标记是标记我们GC ROOT直接引用的对象,在此过程中启动一次STW机制。
如下图所示。
在此插入图像说明
在这个过程中,STW机制会启动,但时间会非常短
2 .同时标记
在并发标记期间,用户线程和CMS线程一起执行。 CMS所做的一件事是在堆中找到并标记所有引用。
但是,在这个过程中可能会发生对象状态发生变化的问题。
例如,我对象的引用链断开,成为垃圾对象,但CMS是否标记他认为不是垃圾对象? (多个问题() () ) ) ) ) )。
另外,原本有一个对象在CMS标记的过程中将他标记为垃圾对象,后来我们有了引用。 结果,在我们使用的时候垃圾对象被杀了。 那么,我们在引用这个对象的时候难道找不到这个垃圾对象吗? 这时我们的第三步应运而生。 (投标遗漏问题)
3 .重新标记
在此步骤中,CMS将启动STW机制,同时标记和修复已更改的对象,但此过程会很长。 他用三种颜色的标记和增量更新解决了我们漏标的问题。 然后,我们将讨论三种颜色的标记和增量更新,并使用Hotspot源代码更深入地了解基础。
4 .同时清理
这一步很好理解。 并发清理是指清理和回收未标记的对象,在此过程中也不会发生STW。
5 .同时复位
将本次GC中的标签数据复位
我相信通过上面的介绍,大家对CMS垃圾回收器的回收步骤有了很清楚的认识。 虽然CMS看起来很强硬,例如多线程操作,例如STW时间很短,但任何东西都有其优缺点。 CMS的缺点有哪些? 我来和你谈谈
二. CMS垃圾回收器的缺点
1 .回收时间长,吞吐量不及并行
由于在执行CMS垃圾回收时将一些资源传递给了用户线程,因此回收时间较长,如果内存空间不立即释放,吞吐量将低于并行
2 .无法处理漂浮垃圾
还记得刚才给大家填了两个洞吗? 我刚才说了再标记,三色标记和增量更新可以解决漏标记的问题。 很多标志实际上到最后都是漂浮垃圾。 漂浮垃圾仅在执行下一次垃圾回收时实际回收。
3 .产生大量空间碎片
为什么会这样呢? 由于我们的CMS垃圾回收算法采用标签去除算法,该算法的弊端是产生空间随意,空间不连续。 但是没关系CMS提供了两个参数来解决这个问题
- xx : usecmscompactatfullcollection
这个参数可以打开内存空间的组织,让我们的空间变得干净。 通常与其他参数联合使用
- xx : cmsfullgcsbeforecompaction
此参数表示CMS在运行full gc多少次后进行空间组织。 这个参数可以不填写。 他默认为0次。 也就是说,每次垃圾回收都整理内存空间。
4 .并发模式失败:并发模型故障
什么意思? 我们老一辈的内存空间满了之后,想想这个时候制作FULL GC,但是在FULL GC的过程中有新的对象进来了怎么办。
此时将进入STW状态,CMS将切换为自动在串行old垃圾收集器中回收。 Serial就我们所知,那是单线程垃圾收集器。 如果发生这种情况,我们的执行效率会不会大幅下降?
为了解决这个问题,我们可以通过调整旧年代的空间充满了多少来触发全GC
- xx : cmsinitiatingoccupancyfraction
如上所述,可以使用此参数调整触发full gc的百分比。 默认值为92%
那么,文章到此结束,接下来的篇将介绍CMS的基础实现原理。 喜欢文章的话请转发哦^^