之前已经讲过了不少有关 GC 的内容,今天准备将之前没有细讲的部分进行补充,首先要提到的就是垃圾收集器。

基础的回收方式有三种:清除压缩复制,衍生出来的垃圾收集器有:

Serial 收集器

新生代收集器,使用停止复制算法,使用一个线程进行 GC ,串行,其它工作线程暂停。

使用-XX:+UseSerialGC开关来控制使用Serial + Serial Old模式运行进行内存回收(这也是虚拟机在 Client 模式下运行的默认值)。

ParNew 收集器

新生代收集器,使用停止复制算法,Serial 收集器的多线程版,用多个线程进行 GC ,并行,其它工作线程暂停,关注缩短垃圾收集时间。

使用-XX:+UseParNewGC开关来控制使用ParNew + Serial Old收集器组合收集内存;使用-XX:ParallelGCThreads来设置执行内存回收的线程数。

Parallel Scavenge 收集器

新生代收集器,使用停止复制算法,关注 CPU 吞吐量,即运行用户代码的时间/总时间,比如:JVM 运行 100 分钟,其中运行用户代码 99 分钟,垃 圾收集 1 分钟,则吞吐量是 99% ,这种收集器能最高效率的利用 CPU ,适合运行后台运算(其他关注缩短垃圾收集时间的收集器,如 CMS ,等待时间很少,所以适 合用户交互,提高用户体验)。

使用-XX:+UseParallelGC开关控制使用Parallel Scavenge + Serial Old收集器组合回收垃圾(这也是在 Server 模式下的默认值);使用-XX:GCTimeRatio来设置用户执行时间占总时间的比例,默认 99 ,即 1% 的时间用来进行垃圾回收。使用-XX:MaxGCPauseMillis设置 GC 的最大停顿时间(这个参数只对 Parallel Scavenge 有效),用开关参数-XX:+UseAdaptiveSizePolicy可以进行动态控制,如自动调整 Eden / Survivor 比例,老年代对象年龄,新生代大小等,这个参数在 ParNew 下没有。

Serial Old 收集器

老年代收集器,单线程收集器,串行,使用标记-整理算法,使用单线程进行GC,其它工作线程暂停(注意:在老年代中进行标记-整理算法清理,也需要暂停其它线程),在JDK1.5之前,Serial Old 收集器与 ParallelScavenge 搭配使用。

整理的方法是 Sweep (清除)和 Compact (压缩),清除是将废弃的对象干掉,只留幸存的对象,压缩是移动对象,将空间填满保证内存分为2块,一块全是对象,一块空闲),

Parallel Old 收集器

老年代收集器,多线程,并行,多线程机制与 Parallel Scavenge 差不错,使用标记-整理算法,在 Parallel Old 执行时,仍然需要暂停其它工作线程。

Parallel Old 收集器的整理,与 Serial Old 不同,这里的整理是Copy(复制)和Compact(压缩),复制的意思就是将幸存的对象复制到预先准备好的区域,而不是像Sweep(清除)那样清除废弃的对象。

Parallel Old 在多核计算中很有用。 Parallel Old 出现后(JDK 1.6),与 Parallel Scavenge 配合有很好的效果,充分体现 Parallel Scavenge 收集器吞吐量优先的效果。使用-XX:+UseParallelOldGC开关控制使用Parallel Scavenge + Parallel Old组合收集器进行收集。

CMS

全称 Concurrent Mark Sweep,老年代收集器,致力于获取最短回收停顿时间(即缩短垃圾回收的时间),使用标记-清除算法,多线程,优点是并发收集(用户线程可以和 GC 线程同时工作),停顿小。

使用-XX:+UseConcMarkSweepGC进行ParNew + CMS + Serial Old进行内存回收,优先使用ParNew + CMS(原因见后面),当用户线程内存不足时,采用备用方案Serial Old收集。

如何开始

首先来看一下 CMS 是在什么情况下进行 GC:

  1. 首先 JVM 根据-XX:CMSInitiatingOccupancyFraction-XX:+UseCMSInitiatingOccupancyOnly来决定什么时间开始垃圾收集。
  1. 如果设置了-XX:+UseCMSInitiatingOccupancyOnly,那么只有当老年代占用确实达到了-XX:CMSInitiatingOccupancyFraction参数所设定的比例时才会触发 CMS GC。
  1. 如果没有设置-XX:+UseCMSInitiatingOccupancyOnly,那么系统会根据统计数据自行决定什么时候触发 CMS GC。因此有时会遇到设置了 80% 比例才 CMS GC,但是 50% 时就已经触发了,就是因为这个参数没有设置的原因。

具体执行

CMS GC 的执行过程,具体来说就是:

初始标记(CMS-initial-mark)

该阶段是 stop the world 阶段,因此此阶段标记的对象只是从 root 集最直接可达的对象。

此阶段会打印 1 条日志:CMS-initial-mark:961330K(1572864K),指标记时,老年代的已用空间和总空间

并发标记(CMS-concurrent-mark)

此阶段是和应用线程并发执行的,所谓并发收集器指的就是这个,主要作用是标记可达的对象,此阶段不需要用户线程停顿。

此阶段会打印 2 条日志:CMS-concurrent-mark-start,CMS-concurrent-mark

预清理(CMS-concurrent-preclean)

此阶段主要是进行一些预清理,因为标记和应用线程是并发执行的,因此会有些对象的状态在标记后会改变,此阶段正是解决这个问题。因为之后的 CMS-remark 阶段也会 stop the world,为了使暂停的时间尽可能的小,也需要 preclean 阶段先做一部分工作以节省时间。

此阶段会打印 2 条日志:CMS-concurrent-preclean-start,CMS-concurrent-preclean

可控预清理(CMS-concurrent-abortable-preclean)

此阶段的目的是使 CMS GC 更加可控一些,作用也是执行一些预清理,以减少 CMS-remark 阶段造成应用暂停的时间。

此阶段涉及几个参数:

    -XX:CMSMaxAbortablePrecleanTime:当 abortable-preclean 阶段执行达到这个时间时才会结束。-XX:CMSScheduleRemarkEdenSizeThreshold(默认2m):控制 abortable-preclean 阶段什么时候开始执行,即当年轻代使用达到此值时,才会开始 abortable-preclean 阶段。-XX:CMSScheduleRemarkEdenPenetratio(默认50%):控制 abortable-preclean 阶段什么时候结束执行。

此阶段会打印 3 条日志:CMS-concurrent-abortable-preclean-start,CMS-concurrent-abortable-preclean,CMS:abort preclean due to time XXX

重新标记(CMS-remark)

此阶段暂停应用线程,停顿时间比并发标记小得多,但比初始标记稍长,因为会对所有对象进行重新扫描并标记。

此阶段会打印以下日志:

  1. YG occupancy:964861K(2403008K),指执行时年轻代的情况。
  1. CMS remark:961330K(1572864K),指执行时老年代的情况。
  1. 此外,还打印出了弱引用处理、类卸载等过程的耗时。

并发清除(CMS-concurrent-sweep)

此阶段进行并发的垃圾清理。

并发重设状态等待下次CMS的触发(CMS-concurrent-reset)

此阶段是为下一次 CMS GC 重置相关数据结构。

总结

CMS 的收集过程,概括一下就是:2 次标记,2 次预清除,1 次重新标记,1 次清除。

在CMS清理过程中,只有初始标记和重新标记需要短暂停顿用户线程,并发标记和并发清除都不需要暂停用户线程,因此效率很高,很适合高交互的场合。

CMS也有缺点,它需要消耗额外的 CPU 和内存资源。在 CPU 和内存资源紧张,会加重系统负担(CMS 默认启动线程数为( CPU数量 + 3 ) / 4 )。

另外,在并发收集过程中,用户线程仍然在运行,仍然产生内存垃圾,所以可能产生“浮动垃圾”(本次无法清理,只能下一次Full GC才清理)。因此在 GC 期间,需要预留足够的内存给用户线程使用。

所以使用 CMS 的收集器并不是老年代满了才触发 Full GC ,而是在使用了一大半(默认 68% ,即 2/3 ,使用-XX:CMSInitiatingOccupancyFraction来设置)的时候就要进行 Full GC。如果用户线程消耗内存不是特别大,可以适当调高-XX:CMSInitiatingOccupancyFraction以降低 GC 次数,提高性能。如果预留的用户线程内存不够,则会触发 Concurrent Mode Failure,此时,将触发备用方案:使用 Serial Old 收集器进行收集,但这样停顿时间就长了,因此-XX:CMSInitiatingOccupancyFraction不宜设的过大。

还有,CMS 采用的是标记-清除算法,会导致内存碎片的产生,可以使用-XX:+UseCMSCompactAtFullCollection来设置是否在 Full GC 之后进行碎片整理,用-XX:CMSFullGCsBeforeCompaction来设置在执行多少次不压缩的 Full GC 之后,来一次带压缩的 Full GC。

并发和并行

并发收集:

指用户线程与GC线程同时执行(不一定是并行,可能交替,但总体上是在同时执行的),不需要停顿用户线程(其实在 CMS 中用户线程还是需要停顿的,只是非常短,GC 线程在另一个 CPU 上执行);

并行收集:

指多个 GC 线程并行工作,但此时用户线程是暂停的;

所以,Serial 是串行的,Parallel 收集器是并行的,而 CMS 收集器是并发的。

总结

今天了解了一下普通的垃圾收集器,并且详细介绍了 CMS,其特性其实是基于普通的垃圾算法,增加了预处理、预清除的过程,因此效率更加优越。当然它也有自己的缺点,更加消耗资源,因此在选用的时候需要结合实际场景。

有兴趣的话可以访问我的博客或者关注我的公众号、头条号,说不定会有意外的惊喜。

https://death00.github.io/

cms是什么意思啊_GC 知识点补充——CMS相关推荐

  1. 计算机网络知识点补充

    计算机网络知识点补充 目录: 1. HTTP和HTTPS的区别 http协议是运行在tcp之上,明文传输,客户端和服务器端都无法验证对方的身份:https是运行在ssl(Secure Socket L ...

  2. set集合以及知识点补充

    str知识点补充: #join() 将列表中的每个元素中间加上一个字符,连接成一个字符串 list = ['a','b','c','d'] str = '*'.join(list) print(str ...

  3. Jaeger知识点补充

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos <Jaeger实战(Java版)>系列全文 ...

  4. 云日记_登出操作个人中心页面js和jsp知识点补充

    用户退出     前端:         设置超链接的请求地址  user?actionName=logout     后台:         1. 销毁Session对象         2. 删除 ...

  5. 到底cms企业建站系统是什么?为什么要做cms系统?

    很多网友都在问为什么cms企业建站系统会突然出现,俗话说一个东西的诞生往往是由于为了满足绝大多数人的需求,至于为什么要做cms系统,到底cms企业建站系统是什么,小编下面简单介绍一下. CMS是Con ...

  6. ecshop文章频道,ecshop文章cms系统,ecshop的CMS文章频道页插件,ECSHOP模板堂CMS文章频道插件

    插件简介 ECSHOP CMS文章频道插件,ecshop类似CMS的文章频道,页面风格采用主流新闻格式,布局利于推广搜索引的收录,良好清晰的文章页结构布局,更利于搜索引擎蜘蛛抓取,让蜘蛛恋上你的网站. ...

  7. dedecms织梦转免费CMS操作步骤(转PageAdmin,帝国CMS、PHPCMS、JTBC、PHPCMS、wordpress)

    dedecms织梦开始正式收费,授权5800元,对于草根站长来说真是太高了,最好的办法是转成免费开源的CMS,下面一些经验之谈,dedecms织梦转PageAdmin,帝国CMS.PHPCMS.JTB ...

  8. Python-day06-2018.7.9_编码以及小知识点补充

    本节知识点: 1.is 和 == 的区别 2.编码的问题 一.is 和 == 的区别 1.id()  通过id我们可以查看到一个变量表示的值在内存中的地址. s = 'alex' print(id(s ...

  9. 基于python的openCV自学笔记(四)——遗漏知识点补充

    本篇补充暑假学opencv遗漏的相关知识点 参考链接:https://www.bilibili.com/video/BV1Fo4y1d7JL?from=search&seid=17628666 ...

最新文章

  1. linux socket 缓冲区默认大小
  2. 002_ZooKeeper安装配置
  3. 旷视研究院博士图鉴|Be that challenger
  4. 数学狂想曲(三)——统计杂谈, PID算法, 20世纪10大算法, 矩阵向量的积
  5. 布局new操作符引发的有关析构函数的探索与总结
  6. 从虚幻4动画系统与控制器交互理解数据驱动(一)古老的写法
  7. 专业能力与行业价值 IBM在华的商业人工智能实践
  8. jQuery的回调管理机制(二)
  9. springboot基于javaweb的课堂考勤系统设计与实现毕业设计源码142335
  10. 计算机错误1327,Win7系统电脑安装软件失败并提示错误1327解决办法
  11. 微信小程序(八 配置和请求)
  12. 小时候玩一天的打砖块小游戏(附完整源码)
  13. 大小写字母的ASCII的对照转换
  14. 两直线平行交叉相乘_向量平行公式和垂直公式
  15. 吴恩达深度学习课程完整笔记(DeepLearning.ai)
  16. xp计算机连接不上网络打印机驱动,解决win10无法连接到XP计算机共享打印机
  17. Jenkins的介绍及使用
  18. Java SSH框架学习(入门)
  19. 数据中心服务器大战:思科vs惠普vs…
  20. DoS网络攻击的类型

热门文章

  1. 码上公益首秀,让科技更有温度!
  2. 赛思互动:企业开展CRM系统需求调研步骤
  3. 《CCNP SWITCH 300-115学习指南》——导读
  4. HDU5709 : Claris Loves Painting
  5. JavaScript变量——栈内存or堆内存
  6. MySQL 5.1中IN查询不要用到NULL条件
  7. 众论英特尔虚拟化之VMware篇
  8. IIS6.0打开ASP文件,出现500错误或404错误解决方法
  9. [2010国家集训队]Crash的旅游计划
  10. 『一本通』差分约束系统