栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

先上一张图

CMS基本介绍

cms垃圾回收器作用于老年代,采用标记清除算法,新生代回收配对的是ParNew,以最短停顿时间为目标,其回收主要经过初始标记,并发标记,重新标记,并发回收 4个阶段,下面来简单介绍下4个阶段所做的事情。

  • 初始标记:暂停所有用户线程,初始标记阶段只标记对与GCRoots直接关联的对象,所以暂停时间很短。
  • 并发标记:这一阶段根据与GCRoots直接关联的对象进行可达性分析,耗时较长,与用户线程同时进行。
  • 重新标记:暂停所有用户线程,主要处理并发标记阶段用户线程运行导致标记产生变动的那一部分对象,时间比初始标记稍长。
  • 并发清除:与用户线程一起运行,根据标记回收对象。
CMS的适用场景及问题
  1. CPU敏感:CMS采用并发收集的方式,当cpu不足4核时,对用户线程影响较大。
  2. 内存碎片:采用标记清除算法,所以会产生内存碎片。
  3. 浮动垃圾:由于采用并发清除,在清除阶段用户线程运行会继续产生垃圾,这些垃圾称为浮动垃圾,所以CMS需要预留一部分堆空间触发回收,如果预留的内存不够存放浮动垃圾,就会出现 Concurrent Mode Failure,这时虚拟机将临时启用 Serial Old 来替代 CMS。

CMS的问题还是比较多的,它并未在任何一个版本中被用作默认的收集器,但是作为第一个并发的>>垃圾回收器,对了解并发垃圾回收有一定的意义,该垃圾回收器适合回收堆空间几个 G~ 20G 左右。

CMS中的三色标记

    在三色标记前有个标记清除算法,初始时标志位为0,如果可达性分析可以到达则标记为1,这个算法的主要问题是GC时需要把所有用户线程都停掉,不可以进行异步的GC,因为在不同的阶段标记的0和1有不同的含义,新增的对象无论标记为0/1都有可能被误删除,三色标记算法就是用来解决 标记清除 算法GC时用户线程长时间挂起的。
    三色标记算法也比较简单,把标记分为三种颜色,黑色,灰色和白色。

  • 黑色:根对象或者该对象以及该对象的可达对象都已经被标记过。
  • 灰色:对象本身被扫描,但与之可到达的下面的对象还未扫描。
  • 白色:未被扫描的对象,如果扫描完成后未被扫描的对象即为需要回收的对象。

CMS漏标的处理,当一个白色标记对象与一个黑色标记对象可达时,把黑色标记改为灰色,让垃圾回收器重新扫描,已确保新产生的对象不会被回收。

G1垃圾回收器介绍

    为了达到STW时间可预测,G1垃圾回收器使用化整为0的思想,把堆空间划分为大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间,Survivor空间,老年代空间,Region中还有一类特殊的Humongous区域,用来存放大对象,G1认为只要大小超过一个Region区域一半的对象都是大对象,可以使用-XX:G1HeapRegionSize 设定,大小为1m~32m且为2的幂次方,回收器可以对扮演不同角色的Region采用不同的策略来处理,这样对于新创建的对象和熬过多次回收的对象都能达到很好的回收效果。

运行过程先来一张图

  • 初始标记:只标记与GCRoots直接相连的对象,并且修改TAMS指针的值,让下一个阶段分配对象时可以正确的在可用Region中分配新的对象。这个阶段需要暂停用户线程,但时间很短,而且借助Minor GC的时候同步完成,所以 G1 收集器在这个阶段实际并没有额外的停顿。

TAMS 全称为 top at mark start,要达到GC与用户线程同时进行,就需要处理运行时新产生的对象,G1为每一个Region设计两个TAMS指针,从 Region 区域划出一部分空间用于记录并发回收过程中的新对象,这些对象时存活的,不会被回收。

  • 并发标记:递归扫描堆中所有对象,耗时较长和用户线程同时进行,当扫描完成后,并发过程中有变动的对象,可能会漏标,根据SATB算法来解决。
  • 最终标记:暂停所有用户线程,这一阶段主要处理上一阶段变动的对象,通过SATB记录。
  • 筛选回收:负责更新 Region 的统计数据,对各个 Region 的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个 Region 构 成回收集,然后把决定回收的那一部分 Region 的存活对象复制到空的 Region 中,再清理掉整个旧 Region 的全部空间。这里的操作涉及存活对象的移动, 是必须暂停用户线程,由多条收集器线程并行完成的。
G1的特点

1.并行和并发: G1 能充分利用多 CPU、多核环境下的硬件优势,使用多个 CPU(CPU 或者 CPU 核心)来缩短 Stop-The-World 停顿的时间
2.分代收集 : 与其他收集器一样,分代概念在 G1 中依然得以保留
3.空间整合: 与 CMS 的“标记—清理”算法不同,G1 从整体来看是基于“标记—整理”算法实现的收集器,从局部(两个 Region 之间)上来看是基于“复 制”算法实现的,但无论如何,这两种算法都意味着 G1 运作期间不会产生内存空间碎片,收集后能提供规整的可用内存
4.追求停顿时间: -XX:MaxGCPauseMillis 指定目标的最大停顿时间,G1 尝试调整新生代和老年代的比例,堆大小,晋升年龄来达到这个目标时间.

G1中的SATB

刚开始做一个快照,当 B 和 C 消失的时候要把这个引用推到 GC 的堆栈,保证 C 还能被 GC 扫描到,最重要的是要把这个引用推到 GC 的堆栈,是灰色对 象指向白色的引用,如果一旦某一个引用消失掉了,我会把它放到栈(GC 方法运行时数据也是来自栈中),我其实还是能找到它的,我下回直接扫描他 就行了,那样白色就不会漏标。

G1中的RSET 和 CardTable

RSET和cardTable主要用来处理跨带引用的。所谓跨带引用,指老年代对象引用新生代,这样在处理新生代的对象回收时,需要遍历老年代对象的引用,这样遍历的话效率很低,G1中使用RSet和CardTable来处理。

  1. RSet
    记录了其他 Region 中的对象到本 Region 的引用, RSet 的价值在于使得垃圾收集器不需要扫描整个堆,找到谁引用了当前分区中的对象,只需要扫描 RSet 即可。 RSet 本身就是一个 Hash 表,如果是在 G1 的话,则是在一个 Region 区里面。
  2. cardTable
    由于做新生代 GC 时,需要扫描整个 OLD 区,效率非常低,所以 JVM 设计了 CardTable,如果一个 OLD 区 CardTable 中有对象指向 Y 区, 就将它设为 Dirty (标志位 1), 下次扫描时,只需要扫描 CARDTABLE 上是 Dirty 的内存区域即可。 字节数组 CARDTABLE 的每一个元素都对应着其标识的内存区域中一块特定大小的内存块,这个内存块被称作“卡页”(Card Page)。 一般来说,卡页大小 都是以 2 的 N 次幂的字节数,假设使用的卡页是 2 的 10 次幂,即 1K,内存区域的起始地址是 0x0000 的话,数组 CARD_TABLE 的第 0、1、2 号元素,分别 对应了地址范围为 0x0000~0x03FF、0x0400 ~ 0x07FF、0x0800~0x011FF 的卡页内存.
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/309939.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号