简述G1垃圾回收器

引入:

G1可以理解为在CMS垃圾收集器上进行”升级”, 老的垃圾回收器STW停顿时间是不可预估的, 而G1垃圾收集器可以可以设定一个Stop The Word 停顿时间,然后根据设定的STW的时间来进行回收
在这里插入图片描述

重新定义了堆空间,打破了原有的分代模型,会将堆内存[逻辑]划分为多个大小相等的Region区域,每个区域独立作为伊甸园、幸存区、老年代、大对象区…
划分为小的区域就可以化整为零,目的在于 加快标记和复制的速度(当堆内存特别大时,g1的优势就很明显)

整体采用标记-整理 算法,两个区域之间用标记-复制算法

大对象
H它代表Humongous,这表示这些Region存储的是大对象(humongous object,H-obj),即超过region一半大的对象,
大对象占内存大,复制成本高,所以不会对大对象进行拷贝,
回收时优先考虑
一旦发现没有引用指向大对象,就可直接在年轻代的Minor GC中被回收掉

优点:
G1最大的特点就在于可预测的停顿时间模型----- 软实时 ,即用户可以指定垃圾回收时间的限时,G1会努力在这个时限内完成垃圾回收

缺点:
G1无论是为了垃圾收集产生的内存占用还是程序运行时的额外执行负载都要比CMS要高。

为什么要将「堆空间」进行「细分」多个小的区域?

堆空间(内存)大的时候,每次进行「垃圾回收」都需要对一整块大的区域进行回收,那收集的时间是不好控制的。而划分为小区域,垃圾回收更容易控制stop the world。

收集器为什么能建立可预测的停顿时间模型?

G1 会通过一个合理的计算模型,将每个 Region 的收集的成本量化,这样一来,收集器在给定了“停顿”时间限制的情况下,总是能选择一组恰当的 Region 作为收集目标,让其收集开销满足这个限制条件。

过程①:Minor GC:

  1. 【当Eden区域满了】,触发Minor GC,用户线程STW,标记GCRoot直接关联的对象
  2. MinorGC是回收新生代对象,当有老年代引用新生代时,这些被引用的对象不能被回收—跨代引用
    在G1中,每个Region区域都有rememberSet记忆集,是个HashTbale, 如果当前Region被老年代对象引用,那么记忆集的key存其他Region的起始地址,value记录其他Card Table的索引集合(新生代的记忆集保存老年代的索引,而老年代的记忆集保存其他老年代的索引),然后将这些记忆集中的对象引用做标记,以免被回收
  3. 使用标记-复制算法,将存活的对象复制到空的幸存区、寿命达到阀值的晋升到老年代
  4. 处理引用队列,软引用,弱引用,虚引用

过程②:Mixed GC:

【当老年代占用堆空间达到阀值】(默认45%,可以调整)会触发MixedGC

  1. 初始标记:只标记一下GC Roots能直接关联到的对象,用户线程STW,老年代和新生代都会扫
  2. 并发标记:用户线程并发运行,根据标记为存活的对象向下追溯遍历,找出所有存活的对象;
  3. 最终标记:是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程 Remembered Set Logs 里面,最终标记阶段需要把 Remembered Set Logs 的数据合并到 Remembered Set 中,这阶段需要停顿线程,但是可并行执行。
  4. 筛选回收:用户线程STW,会根据设定的停顿时间,由「停顿预测模型」来决定回收哪些Region,
    一次回收未必是将所有的垃圾进行回收的,G1会依据停顿时间来选择回收Region的数量

过程③:Full GC:

当回收的速度跟不上分配内存的速度了,无法Mixed GC,造成并发失败触发FullGC,这时老年代并发垃圾回收器会退化到SerialOld 串行垃圾回收器并进行整理,

CMS一样,在并发失败后,会退回SerialGC串行垃圾回收— FullGC

Minor GC中的跨代回收

当对新生代垃圾回收时,新生代的部分对象被老年代所引用,而老年代存对象多,不可能全部去扫描,则使用 Card Table技术,将老年代分成一个个Card
如果老年代中的对象引用了新生代的对象,则对应的Car被标记为dirty card 脏卡,对应新生代的RemenberedSet记忆集会标记对用的脏卡,避免遍历整个老年代去查找对新生代的引用,以提高效率。
在这里插入图片描述

将来在对新生代进行垃圾回收时,可以先通过RenmeneredSet知道对应的脏卡,再到老年代的脏卡区域去遍历GC Root,这样减少了GC Root遍历的时间

脏卡通过post-write barrier 写屏障,在每次对象引用发生变更时,都要去更新脏卡,此为异步操作,会将更新脏卡的指令放到 dirty card queue 队列中由线程去实现。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值