zoukankan      html  css  js  c++  java
  • CMS和G1

    新生代收集器的收集频率较高,应选用性能高效的收集器;而老年代收集器次数相对较少,对空间较为敏感,应当避免选择基于复制算法的收集器;

    在垃圾收集执行的时刻,应用程序需要暂停运行;可以串行收集,也可以并行收集

    • 为什么没有一种收集器可以适配所有场景?
    • CMS的优点、缺点、适用场景?
    • 为什么CMS只能用作老年代收集器,而不能应用在新生代的收集?
    • G1的优点、缺点、适用场景?

    CMS收集器-->Concurrent Mark Sweep

    CMS收集器是一种以获取最短回收停顿时间为目标的收集器。CMS收集器工作时,GC工作线程与用户线程可以并发执行,以此来达到降低收集停顿时间的目的。

    CMS收集器仅作用于老年代的收集,是基于标记-清楚算法的:

    • 初始标记:需要Stop-the-world。初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快
    • 并发标记:并发标记阶段就是进行GC Roots Tracing的过程
    • 重新标记:重新标记阶段是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始阶段稍长一些,但远比并发阶段的时间短
    • 并发清除

    CMS以流水线方式拆分了收集周期,将耗时长的操作单元保持与应用线程并发执行。只将那些必须STW才能执行的操作单元单独拎出来,控制这些单元在恰当的时机运行,并能保证仅需短暂的时间就可以完成。这样,在整个收集周期内,只有两次短暂的暂停(初始标记和重新标记),达到了近似并发的目的

    CMS收集器优点:并发收集、低停顿

    CMS收集器缺点:CMS收集器对CPU资源非常敏感;CMS收集器无法处理浮动垃圾;CMS收集器是基于标记-清除算法,该算法的缺点都有

    CMS收集器之所以能够做到并发,根本原因在于采用基于“标记-清除”的算法并对算法过程进行了细粒度的分解。

    标记-清楚算法将产生大量的内存碎片,这对新生代来说是难以接受的,因此新生代的收集器并未提供CMS版本

    JVM在暂停的时候,需要选准一个时机。由于JVM系统运行期间的复杂性,不可能做到随时暂停,因此引入了安全点的概念

    安全点Safepoint-->程序执行时并非在所有地方都能停顿下来开始GC,只有在到达安全点时才能暂停。Safepoint的选定既不能太少以至于让GC等待时间太长,也不能过于频繁以至于过分增大运行时的负荷

    安全点的初始目的并不是让其他线程停下,而是找到一个稳定的执行状态。在这个执行状态下,Java虚拟机的堆栈不会发生变化。这样,垃圾回收器就能够安全地执行可达性分析。只要不离开这个安全点,Java虚拟机便能够在垃圾回收的同时,继续运行这段本地代码

    安全点的选定基本上是以程序“是否具有让程序长时间执行的特征”为标准进行选定的。“长时间执行”的最明显特征就是指令序列复用,如方法调用、循环跳转、异常跳转等,具有这些功能的执行才会产生Safepoint

    对于安全点,另一个需要考虑的问题就是如何在GC发生时让所有线程都跑到最近的安全点上再停顿下来-->两种解决方案

    抢先式中断:抢先式中断不需要线程的执行代码主动去配合,在GC发生时,首先把所有线程全部中断,如果发现有线程中断的地方不在安全点上,就恢复线程,让它跑到安全点上

    主动式中断

    G1收集器-->G1收集器重新定义了堆空间,打破了原有的分代模型,将堆划分为一个个区域。目的是在进行收集时不必在全堆范围内进行,这是它最显著的特点。区域划分的好处就是带来了停顿时间可预测的收集模型,用户可以指定收集操作在多长时间内完成。G1提供了接近实时的收集特性

    特征                                        G1          CMS

    并发和分代                             是             是

    最大化释放堆内存                  是             否

    低延时                                    是             是

    吞吐量                                    高             低

    压实                                        是             否

    可预测性                                 强             弱

    新生代和老年代的物理隔离    否             是

    G1具备如下特点:

    并行与并发:G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU来缩短Stop-the-world停顿的时间,部分其他收集器原来需要停顿Java线程执行的GC操作,G1收集器仍然可以通过并发的方式让Java程序继续执行

    分代收集

    空间整合:基于标记-整理算法实现的收集器,从局部(两个Region之间)上来看是基于"复制"算法实现的。但无论如何,这两种算法都意味着G1运作期间不会产生内存碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC

    可预测的停顿:这是G1相对于CMS的一个优势,降低停顿时间是G1和CMS共同的关注点

    在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。在堆的结构设计时,G1打破了以往将收集范围固定在新生代或老年代的模式,G1将堆分成许多相同大小的区域单元,每个单元称为Region。Region是一块地址连续的内存空间,

    G1收集器将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。Region的大小是一致的,数值是在1M到32M字节之间的一个2的幂值数,JVM会尽量划分2048个左右、同等大小的Region。

    G1收集器之所以能建立可预测的停顿时间模型,是因为它可以有计划地避免在整个Java堆中进行全区域的垃圾收集。G1会通过一个合理的计算模型,计算出每个Region的收集成本并量化,这样,收集器在给定了“停顿”时间限制的情况下,总是能选择一组恰当的Regions作为收集目标,让其收集开销满足这个限制条件,以此达到实时收集的目的

    运作过程-->

    初始标记:仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS的值,让下一阶段用户程序并发运行时,能在正确可用的Region中创建新对象,这阶段需要停顿线程,但耗时很短

    并发标记:是从GC Roots开始堆中对象进行可达性分析,找出存活的对象,这阶段耗时较长,但可与用户程序并发执行

    最终标记:是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程Remembered Set Logs里面,最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set中,这阶段需要停顿线程,但是可并行执行。

    筛选回收:首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。这个阶段也可以做到与用户程序一起并发执行,但是因为只回收一部分Region,时间是用户可控制的,而且停顿用户线程将大幅提高收集效率

  • 相关阅读:
    cdoj1325卿学姐与基本法
    HUAS 1476 不等数列(DP)
    BZOJ 1818 内部白点(离散化+树状数组)
    BZOJ 1816 扑克牌(二分)
    BZOJ 1801 中国象棋(DP)
    BZOJ 1791 岛屿(环套树+单调队列DP)
    BZOJ 1797 最小割(最小割割边唯一性判定)
    BZOJ 1789 Y形项链(思维)
    BZOJ 1787 紧急集合(LCA)
    BZOJ 1786 配对(DP)
  • 原文地址:https://www.cnblogs.com/liushoudong/p/12945321.html
Copyright © 2011-2022 走看看