• JVM(二十二)—— 垃圾回收器(二)CMS垃圾回收器


    CMS垃圾回收器

    在JDK5,HotSpot推出了一款在强交互应用中几乎可认为有划时代意义的垃圾收集器CMS(Concurrent Mark Sweep)收集器,这款收集器是HotSpot虚拟机中第一款真正意义上的并发收集器,他第一次实现了让垃圾收集线程与用户线程同时工作。

    CMS收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时。停顿时间越短(低延迟)就越适合与用户交互的程序,良好的响应速度能提升用户体验。

    目前很大一部分的Java应用集中在互联网站或者B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,以带给用户较好的体验。CMS收集器就非常符合这类应用的需求。

    CMS的垃圾收集孙发采用标记清除算法,并且也会STW.

    在这里插入图片描述
    CMS作为老年代的收集器,却无法与JDK4中已经存在的新生代收集器Parallel Scavenge配合工作,所以在JDK5中使用CMS 来收集老年代的时候,新生代只能选择ParNew或者Serial 收集器中的一个。
    在G1出现之前,CMS使用还是非常广泛的,一直到今天,仍然有很多系统使用CMS垃圾收集器。

    CMS工作原理

    在这里插入图片描述
    CMS整个过程比之前的收集器更复杂,整个过程分为4个主要阶段。即初始标记阶段,并发标记阶段,重新标记 阶段和并发清除阶段。

    • 初始标记阶段: 在这个阶段中,程序中所有的工作线程都将会因为STW机制而出现短暂的暂停,这个阶段的主要任务仅仅只是标记出GC Roots能直接关联到的对象。一旦标记完成之后就会恢复之前被暂停的所有应用线程。由于直接关联对象比较小,所以这里的速度非常快。
    • 并发标记阶段: 从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程仪器并发运行。
    • 重新标记阶段: 由于并发标记阶段中,程序的工作线程会和垃圾收集线程同时运行或者交叉运行**,因此为了修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录**,这个阶段的停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短。
    • 并发清除阶段:此阶段清理删除掉标记阶段判断的已经死亡的对象,释放内存空间。由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的。

    CMS的特点

    尽管CMS收集器采用的是并发回收(非独占式),但是在其初始化标记和在此标记这两个阶段中仍然需要执行STW机制暂停程序中的工作线程,不过暂停时间并不会太长,因此可以说明目前所有的垃圾收集器都做不到完全不需要STW,只是尽可能缩短暂停时间。

    由于嘴耗费时间的并发标记与并发清除阶段都不需要暂停工作,所以整体的回收是低停顿的。

    另外,由于在垃圾收集阶段用户线程没有中断,所以在CMS回收过程中,还应该确保应用程序用户线程有足够的内存可用。因此CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了咱进行手机,而是当堆内存使用率达到某一阈值时,便开始进行回收,以确保应用程序在CMS工作过程中依然有足够的的空间支持应用程序运行。要是CMS运行期间预留的内存无法满足程序需要,就会出现一次“Comcurrent Mode Failure”失败,这时虚拟机将启动后备方案,临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样停顿的时间就很长了。

    在这里插入图片描述
    CMS收集器的垃圾收集算法采用的是标记清除算法, 这意味着每次执行完内存回收后,由于被执行内存回收的无用对象所占用的内存空间极有可能是不连续的一些内存块,不可避免地将会产生一些内存碎片。那么CMS在为新对象分配内存空间时,将无法使用指针碰撞技术。而只能够选择空闲列表执行内存分配。

    为什么CMS会产生内存碎片,不使用标记整理算法呢?
    因为在并发清除的时候,用标记整理算法整理内存的话,原来的用户线程使用的内存地址就会发生变化。要保证用户线程能继续执行,前提是它运行的资源不收影响。标记压缩算法更适合STW这种场景下使用。

    CMS的优缺点

    • 优点

      • 并发收集
      • 低延迟
    • 缺点

      • 会产生内存碎片:导致并发清除后,用户线程可用的空间不足。在无法分配大对象的情况下,不得不提前触发Full GC.
      • CMS收集器对CPU资源非常敏感。在并发阶段,他虽然不会导致用户停顿,但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。
      • CMS收集器无法处理浮动垃圾: 可能出现 “Comcurrent Mode Failure” 失败而导致另一次Full GC.在并发标记阶段由于程序的工作线程和垃圾收集线程是同时运行或交叉运行的,那么在并发标记阶段如果产生新的垃圾对象,CMS将无法对这些垃圾对象进行标记,最终会导致这些新产生的垃圾对象没有被及时回收,从而只能下一次执行GC时释放这些之前未被回收的内存空间。

    CMS参数设置

    在这里插入图片描述
    在这里插入图片描述

    CMS在后续版本的变化

    在这里插入图片描述

  • 相关阅读:
    栈的多种C语言实现 编程
    RabbitMQ:发布确认高级
    安全好用性价比高的远程协同运维软件有吗?
    python可视化分析(九)-绘制金字塔图
    Qt进程间通信(QSharedMemory、QLocalSocket、QWebSocket、QProcess、D-BUS、QTcpSocket)
    区块链技术中的共识机制算法:以工作量证明(PoW)为例
    连锁店如何通过连锁收银系统做会员营销
    Python日学壹技:性能分析
    以太坊EVM智能合约中的数据存储
    Pytest插件
  • 原文地址:https://blog.csdn.net/weixin_40920359/article/details/127831657