CMS:以获取最短回收停顿时间为目标的收集器,基于并发“标记清理”实现

有人会好奇为什么标记清理算法会产生内存碎片!但是CMS仍采用这种算法呢?

答案是:因为CMS作为第一款实现用户线程和收集线程并发执行的收集器!当时的设计理念是减少停顿时间,最好是能并发执行!但是问题来了,如要用户线程也在执行,那么就不能轻易的改变堆中对象的内存地址!不然会导致用户线程无法定位引用对象,从而无法正常运行!而标记整理算法和复制算法都会移动存活的对象,这就与上面的策略不符!因此CMS采用的是标记清理算法!

              初始标记-->并发标记---->重新标记---->并发清理

过程:

1、初始标记:独占PUC,stop-the-world, 仅标记GCroots能直接关联的对象

2、并发标记:可以和用户线程并发执行,通过GCRoots Tracing 标记所有可达对象

3、重新标记:独占CPU,stop-the-world, 对并发标记阶段用户线程运行产生的垃圾对象进行标记修正,以及更新自我拯救那部分逃逸对象

4、并发清理:可以和用户线程并发执行,清理垃圾

优点:

并发,低停顿

缺点:

1、对CPU非常敏感:在并发阶段虽然不会导致用户线程停顿,但是会因为占用了一部分线程使应用程序变慢

2、无法处理浮动垃圾:在最后一步并发清理过程中,用户线程执行也会产生垃圾,但是这部分垃圾是在标记之后,所以只有等到下一次gc的时候清理掉,这部分垃圾叫浮动垃圾。由于并发清理的时候,用户线程也在运行,就需要保证用户线程在运行的时候需要留有部分内存以供使用。但是当这部分内存不足以给用户线程正常使用时,就会出现一次 “Concurrent Mode Failure,一旦出现了“Concurrent Mode Failure”,便会开启后备方案,临时使用SerialOld收集器进行收集工作。

3、CMS使用“标记-清理”法会产生大量的空间碎片,当碎片过多,将会给大对象空间的分配带来很大的麻烦,往往会出现老年代还有很大的空间但无法找到足够大的连续空间来分配当前对象,不得不提前触发一次FullGC

为了解决这个问题CMS提供了一个开关参数,用于在CMS顶不住,要进行FullGC时开启内存碎片的合并整理过程,但是内存整理的过程是无法并发的,空间碎片没有了但是停顿时间变长了

CMS 出现FullGC的原因:

1、年轻代晋升到老年代没有足够的连续空间,很有可能是内存碎片导致的,因此会触发FULL GC

2、在并发过程中JVM觉得在并发过程结束之前堆就会满,需要提前触发FullGC

CMS失败后使用备案SerialOld收集器


G1:是一款面向服务端应用的垃圾收集器

初始标记-->并发标记---->最终标记---->筛选回收

            G1只有并发标记阶段能做到用户线程和回收线程并发执行!!!!

G1可以不需要其它收集器配合就能独立管理整个GC堆

目标是替换掉CMS收集器

特点:

1、并行与并发:G1能充分利用CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短stop-The-World停顿时间。部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让java程序继续执行。

2、分代收集:分代概念在G1中依然得以保留。虽然G1可以不需要其它收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。也就是说G1可以自己管理新生代和老年代了。

3、空间整合,没有内存碎片产生:由于G1使用了独立区域(Region)概念,G1从整体来看是基于“标记-整理”算法实现收集,从局部(两个Region)上来看是基于“复制”算法实现的,但无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片。

在最后筛选回收阶段,对每个region里的回收对象价值(回收该区域的时间消耗和能得到的内存比值)最后进行排序,用户可以自定义停顿时间,那么G1就可以对部分的region进行回收!这使得停顿时间是用户自己可以控制的!!!!

但是每个region之间是有互相引用的依赖关系的!这导致在MinorGC的时候会同时对老年代进行扫描(甚至是整个堆扫描),那就会导致MinorGC的效率低下,时间变长!

如何解决???

维护一个Remebered Set集合来存放各个Region之间的引用关系!当进行GC Roots Tracing 的时候就可以只扫描set里的关联region!而不用全堆扫描啦!!!

4、可预测的停顿:这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用这明确指定一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。

可预测的停顿什么意思呢?

G1可以有计划的避免在整个JAV堆中进行垃圾收集,可以对每个region里的回收对象价值(回收该区域的时间消耗和能得到的内存比值)进行分析,在最后筛选回收阶段,对每个region里的回收对象价值(回收该区域的时间消耗和能得到的内存比值)最后进行排序,用户可以自定义停顿时间,那么G1就可以对部分的region进行回收!这使得停顿时间是用户自己可以控制的!!!!


与其它收集器相比,G1变化较大的是它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留了新生代和来年代的概念,但新生代和老年代不再是物理隔离的了它们都是一部分Region(不需要连续)的集合。同时,为了避免全堆扫描,G1使用了Remembered Set来管理相关的对象引用信息。当进行内存回收时,在GC根节点的枚举范围中加入Remembered Set即可保证不对全堆扫描也不会有遗漏了。

最后筛选回收阶段首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划(可预测的停顿,这一过程同样是需要停顿线程的,但Sun公司透露这个阶段其实也可以做到并发,但考虑到停顿线程将大幅度提高收集效率,所以选择停顿。下图为G1收集器运行示意图:

JVM: G1和CMS的区别相关推荐

  1. 【重难点】【JVM 03】CMS、G1、ZGC

    [重难点][JVM 03]CMS.G1.ZGC 文章目录 [重难点][JVM 03]CMS.G1.ZGC 一.CMS 1.介绍 2.优点 3.缺点 二.G1 1.介绍 2.优势 3.应用场景 4.Re ...

  2. CMS收集器和G1收集器的区别

    目录 CMS收集器和G1收集器的区别 区别一: 使用范围不一样 区别二: STW的时间 区别三: 垃圾碎片 区别四: 垃圾回收的过程不一样 对于CMS收集器和G1收集器的不同,目前简单写了一下4点,有 ...

  3. 一网打尽!CMS收集器和G1收集器的区别

    CMS 收集器 CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器.它非常符合在注重用户体验的应用上使用. CMS(Concurrent Mark S ...

  4. JVM - G1初探

    文章目录 GC概述 G1的内存分区 G1回收垃圾的几个阶段 初始标记 (initial mark,STW) 并发标记(Concurrent Marking) 最终标记(Remark,STW) 筛选回收 ...

  5. G1 vs CMS vs平行GC

    这篇文章是我们一年前进行的实验的跟进,比较了现实环境中不同GC算法的性能. 我们进行了相同的实验,将测试扩展为包含G1垃圾收集器,然后在不同的平台上运行了测试. 今年,我们的测试使用了以下垃圾收集器: ...

  6. G1与CMS垃圾回收

    个人博客请访问 http://www.x0100.top G1 GC,全称Garbage-FirstGarbage Collector,通过-XX:+UseG1GC参数来启用,作为体验版随着JDK 6 ...

  7. JVM G1垃圾收集器

    Garbage-First(后文简称G1)收集器是当今收集器技术发展的最前沿成果,在Sun公司给出的JDK RoadMap里面,它被视作JDK 7的HotSpot VM 的一项重要进化特征.从JDK ...

  8. G1和CMS的三色标记法及漏标问题

    首先标记有三个阶段: 初始标记 -> 并发标记 -> 最终标记  ->  (拷贝存活区域对象) 初始标记: 只会标记GCRoot直接关联的对象 并发标记: 基于初始标记时标记的对象作 ...

  9. jvm与jit编译器的区别_了解jvm和jit编译器的第1部分

    jvm与jit编译器的区别 Hello people!! 大家好!! I can see that the Java community is growing a lot but there are ...

最新文章

  1. Windows和Linux如何使用Java代码实现关闭进程
  2. [javaEE] JDBC快速入门
  3. pcdmis怎么导出模型_从代数几何到导出代数几何:复形的几何
  4. 素数类型C语言题目总结
  5. Linux下查看系统版本号信息的方法(转)
  6. python物业管理系统_小型物业管理系统的设计与实现研究背景及意义
  7. web基础_$POST 在线http接口测试网址
  8. linux qq传文件怎么安装,在Ubuntu Linux下怎样安装QQ
  9. 图像坐标球面投影_一种将球面图像投影至平面图像的方法与流程
  10. 【车间调度】基于matlab改进的帝国企鹅算法求解车间调度问题【含Matlab源码 2041期】
  11. [Java] 类和对象(简介,封装,内存机制,构造方法)
  12. linux 格式化工具 mkfs 简介
  13. 详解Python中get函数的用法(附代码)
  14. Casbin入选2022 Google编程之夏
  15. 使用scrapy简单爬取网易新闻
  16. xadmin的一些自定义
  17. 【中断】异常和中断的关系、异常向量表和中断向量表的关系
  18. 一周自学动态网站设计
  19. 7本不错的HTML 5书籍推荐
  20. 基于Java汽车配件销售业绩管理系统设计实现(源码+lw+部署文档+讲解等)

热门文章

  1. android开发超级群(500人)
  2. OpenCV中6种访问Mat元素的方法
  3. Mathematica基础——Part——[[]]
  4. 音视频流媒体的原理以及基础入门知识
  5. linux命令之创建符号连接-ln
  6. DLL中导出函数的声明有两种方式
  7. 图像增强——基于OpenCV的图像色彩增强
  8. 定位插件_微创新 | 开发PL/SQL插件,快速定位所需字段
  9. 【转】误差矩阵(混淆矩阵)评价法
  10. tcp http https