概述

  • CMS为基于标记清除算法实现的多线程老年代垃圾回收器。CMS为响应时间优先的垃圾回收器,适合于应用服务器,如网络游戏,电商等和电信领域的应用。
  • 为了实现这个目的,与其他垃圾回收器不同的是,CMS是与应用程序并发执行的,即在CMS对老年代进行垃圾回收时,应用程序大部分时间里是可以继续执行的,应用程序只需进行非常短暂的停顿。由于与应用程序并发执行,同一时刻同时存在垃圾回收线程和应用线程,故对服务器的CPU消耗较大,需要保证服务器CPU资源充足。

执行过程

  1. 初始标记:应用程序需要停顿,主要是收集GC roots直接引用的对象并标记这些对象为存活对象,这些对象可能在新生代或者老年代,即需要对整个堆进行扫描,不过由于直接引用的对象较少,故不需要消耗很长的时间;
  2. 并发标记:与应用程序并发执行,从初始标记阶段所收集到的GC roots直接引用的对象出发,继续扫描查找和标记可达的对象,这个过程涉及到整个堆,即包括新生代和老年代,故需要耗费较长时间,所以与应用程序并发执行,不会对应用程序造成干扰;
  3. 并发预清理:并发预清理主要是将新生代中在并发标记阶段中晋升到老年代的对象进行清理,减少新生代中对象的数量,减少下一阶段重新标记需要扫描的对象数量。并发预清理阶段默认执行时间不能超过5s,否则直接进入重新标记阶段,默认值5s可以通过JVM参数:-XX:CMSMaxAbortablePrecleanTime 来调整。除此之外,还可以通过JVM参数:-XX:+CMSScavengeBeforeRemark 来开启在进行重新标记Remark之前,强制对新生代执行一次MinorGC,从而减少重新标记阶段需要扫描的对象数量,减少Remark的执行时间;
  4. 重新标记:应用程序需要停顿,由于并发标记阶段,应用程序在并发执行,故可能会产生新的垃圾对象,或者原来的垃圾对象重新变为可达,故在该阶段暂停应用,然后对在并发标记阶段中状态发生了变化的对象进行重新标记,此过程涉及到整个堆中,即从GC roots引用的对象出发,对新生代和老年代中发生了变化的对象进行重新标记。具体remark阶段的执行时间,可以通过GC日志的CMS-remark日志内存来查看。
  5. 并发清除:将以上过程没有被标记为可达的对象进行清除,此阶段是与应用程序并发执行的;
  6. 并发重置:对该次CMS垃圾回收中的数据结构进行重置,以便下次进行CMS。

日志分析

  • 以上过程的执行时间都可以通过配置:-XX:+PrintGCDetails,来打印详细的GC日志来查看,如下:

    [GC [ParNew: 839977K->1563K(943744K), 0.0048690 secs] 994555K->156183K(3040896K), 0.0052340 secs] [Times: user=0.02 sys=0.01, real=0.01 secs] [GC [1 CMS-initial-mark: 629255K(2097152K)] 631951K(3040896K), 0.0066920 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
    [CMS-concurrent-mark: 1.385/1.385 secs] [Times: user=4.80 sys=0.29, real=1.38 secs]
    [CMS-concurrent-preclean: 0.008/0.008 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
    [GC [ParNew: 840863K->2737K(943744K), 0.0079350 secs] 1470119K->632187K(3040896K), 0.0084240 secs] [Times: user=0.03 sys=0.01, real=
    0.01 secs]
    [CMS-concurrent-abortable-preclean: 0.646/1.471 secs] [Times: user=2.48 sys=0.27, real=1.47 secs]
    [GC[YG occupancy: 424421 K (943744 K)][Rescan (parallel) , 0.0519000 secs][weak refs processing, 0.0017730 secs] [1 CMS-remark: 6294
    50K(2097152K)] 1053871K(3040896K), 0.0538830 secs] [Times: user=0.32 sys=0.01, real=0.05 secs]
    [CMS-concurrent-sweep: 0.971/0.971 secs] [Times: user=2.06 sys=0.19, real=0.97 secs]
    [CMS-concurrent-reset: 0.012/0.012 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
    

优缺点

  • CMS垃圾回收的特点是应用程序可以并发执行,所以应用停顿时间较短,实现了高响应时间的目的。缺点方面除了需要消耗较多的CPU资源外,由于是基于标记清除算法,故会造成内存碎片。为了解决内存碎片问题,CMS提供了JVM参数:-XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=1,来配置在进行了Full GC时,对老年代进行压缩整理,处理掉内存碎片,其中CMSFullGCsBeforeCompaction配置进行了多少次Full GC之后执行一次内存压缩。
  • 与Parallel一样,也可以通过:-XX:ParallelGCThreads来配置并行垃圾回收线程数。
  • Concurrent Mode Failure:由于CMS在执行过程中是与应用程序并发执行的,如果在此过程中,应用程序需要在老年代分配空间来存放对象,而老年代此时没有足够的空闲空间,此时会触发Concurrent Mode Failure,之后会进行一次Full GC,老年代降级为使用Serial Old垃圾回收器,此时会暂停所有的应用线程的执行。

并行并发CMS垃圾回收器:-XX:+UseConcMarkSweepGC相关推荐

  1. c++ 多线程 垃圾回收器_并行并发CMS垃圾回收器:-XX:+UseConcMarkSweepGC

    概述 CMS为基于标记清除算法实现的多线程老年代垃圾回收器.CMS为响应时间优先的垃圾回收器,适合于应用服务器,如网络游戏,电商等和电信领域的应用. 为了实现这个目的,与其他垃圾回收器不同的是,CMS ...

  2. 关于CMS垃圾回收器的几个问题

    本文来说下关于CMS垃圾回收器的几个问题 文章目录 什么是CMS 使用场景 缺点 实现机制 周期性Old GC 触发条件 晋升担保失败 周期性Old GC过程 InitialMarking(初始化标记 ...

  3. CMS垃圾回收器详解

    垃圾回收器组合 young Tenured JVM options Serial Serial -XX:+UseSerialGC Parallel Scavenge Serial -XX:+UsePa ...

  4. CMS垃圾回收器和G1垃圾回收器区别

    1.引言 我们知道java在C++语言的基础上演变而来.java垃圾回收机制是java和C++等语言的一个重要区别,让java程序员可以不用像C++程序员那样为内存回收而提心吊胆,而是专注于业务逻辑. ...

  5. CMS垃圾回收器介绍

    1. CMS垃圾回收器 CMS是老年代回收器,只能回收老年代的对象,在收集过程中可以与用户线程并发操作.CMS牺牲了系统的吞吐量来追求收集速度,适合追求垃圾收集速度的服务器上.CMS收集器可以通过参数 ...

  6. CMS垃圾回收器与G1垃圾回收器

    CMS垃圾回收器与G1垃圾回收器 先上一张图 CMS基本介绍 cms垃圾回收器作用于老年代,采用标记清除算法,新生代回收配对的是ParNew,以最短停顿时间为目标,其回收主要经过初始标记,并发标记,重 ...

  7. g1垃圾回收器与cms垃圾回收器详解及最佳实践

    2019独角兽企业重金招聘Python工程师标准>>> G1垃圾收集器入门 说明 concurrent: 并发, 多个线程协同做同一件事情(有状态) parallel: 并行, 多个 ...

  8. 【拥抱大厂系列】面试官100%会严刑拷打的 CMS 垃圾回收器,下次面试就拿这篇文章怼回去!

    点个赞,看一看,好习惯!本文 GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了3个月总结的一线大厂Java面试总结,本人已拿腾 ...

  9. 面试官 100% 会严刑拷打的 CMS 垃圾回收器,下次面试就拿这篇文章怼回去!

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:牛人 20000 字的 Spring Cloud 总结,太硬核了~ 这里跟大家讲个面试的最常见的垃圾回收器的问题 ...

最新文章

  1. 对python来说、一个模块就是一个文件-Python如何将将模块分割成多个文件
  2. Spring 配置标签——util标签
  3. 【机器学习基础】数学推导+纯Python实现机器学习算法24:LightGBM
  4. 09.multi-get api操作
  5. 服务器出生点配置文件,服务器设置出生点
  6. Android应用开发系列课程------ViewPager与ViewFlipper较量
  7. 获取少女资源.html,战舰少女资源怎么得 资源来源汇总
  8. oracle u4e00 u9fa5,Oracle 判断汉字 [\u4e00-\u9fa5]
  9. LINUX:read命令
  10. asynchttpclient 超时_英雄联盟手游登录超时解决办法 登录超时如何解决_游戏花边...
  11. ASP.NET MVC 学习第三天
  12. 笔记软件对比之 思源笔记 VS Notion
  13. java调试查看调用堆栈_关于调试:如何阅读和理解java堆栈跟踪?
  14. 2022年软件工程师报告出炉,年薪最高的是...
  15. 更改电脑本地用户名,将中文用户名给为英文名称
  16. SMART 关键指标解析, 如何通过解读 SMART 信息预测硬盘故障
  17. Java开发——IDEA
  18. 因子模型:套利定价理论APT
  19. spine 动态换皮功能
  20. python什么是调用_什么是Python中的可调用?

热门文章

  1. Python数据分析辅助审计工作
  2. 利用PRM-DUL工具恢复oracle dbf文件中的数据
  3. 【BZOJ】1665: [Usaco2006 Open]The Climbing Wall 攀岩(spfa)
  4. 苹果11怎样设置自动锁屏 iPhone11自动锁屏操作方法
  5. mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
  6. linux根据端口查找进程,linux根据端口查找进程
  7. Zigbee HA 框架学习笔记
  8. html css分别是什么单位,CSS的deg是什么单位?
  9. 线上测评图形题技巧一
  10. 哈工大计算机网络考研题,哈工大计算机考研历年复试试题(完全版).PDF