前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >G1垃圾收集器(6)之Young GC

G1垃圾收集器(6)之Young GC

作者头像
黑洞代码
发布2021-05-17 12:35:13
4.7K2
发布2021-05-17 12:35:13
举报
文章被收录于专栏:落叶飞翔的蜗牛

G1的垃圾收集模式

G1中有两种回收模式:

1.完全年轻代GC(fully-young collection),也称年轻代垃圾回收(Young GC)2.部分年轻代GC(partially-young collection)又称混合垃圾回收(Mixed GC)

年轻代垃圾回收(完全年轻代GC)

完全年轻代GC是只选择年轻代区域(Eden/Survivor)进入回收集合(Collection Set,简称CSet)进行回收的模式。年轻代GC的过程和其他的分代回收器差不多,新创建的对象分配至Eden区域,然后将标记存活的对象移动至Survivor区,达到晋升年龄的就晋升到老年代区域,然后清空原区域(不过这里可没有年轻代复制算法中两个Survivor的交换过程)。

年轻代GC会选择所有的年轻代区域加入回收集合中,但是为了满足用户停顿时间的配置,在每次GC后会调整这个最大年轻代区域的数量,每次回收的区域数量可能是变化的

下面是一个完全年轻代GC过程的简单示意图:将选择的年轻代区域中所有存活的对象,移动至Survivor区域,然后清空原区域

年轻代垃圾回收过程

当JVM无法将新对象分配到eden区域时,会触发年轻代的垃圾回收(年轻代垃圾回收是完全暂停的,虽然部分过程是并行,但暂停和并行并不冲突)。也会称为“evacuation pause”

步骤1. 选择收集集合(Choose CSet),G1会在遵循用户设置的GC暂停时间上限的基础上,选择一个最大年轻带区域数,将这个数量的所有年轻代区域作为收集集合。

如下图所示,此时A/B/C三个年轻代区域都已经作为收集集合,区域A中的A对象和区域B中的E对象,被ROOTS直接引用(图上为了简单,将RS直接引用到对象,实际上RS引用的是对象所在的CardPage)

步骤2. 根处理(Root Scanning),接下来,需要从GC ROOTS遍历,查找从ROOTS直达到收集集合的对象,移动他们到Survivor区域的同时将他们的引用对象加入标记栈

如下图所示,在根处理阶段,被GC ROOTS直接引用的A/E两个对象直接被复制到了Survivor区域M,同时A/E两个对象所引用路线上的所有对象,都被加入了标记栈(Mark Stack),这里包括E->C->F,这个F对象也会被加入标记栈中

步骤3. RSet扫描(Scan RS),将RSet作为ROOTS遍历,查找可直达到收集集合的对象,移动他们到Survivor区域的同时将他们的引用对象加入标记栈

在RSet扫描之前,还有一步更新RSet(Update RS)的步骤,因为RSet是先写日志,再通过一个Refine线程进行处理日志来维护RSet数据的,这里的更新RSet就是为了保证RSet日志被处理完成,RSet数据完整才可以进行扫描

如下图所示,老年代区域C中引用年轻代A的这个引用关系,被记录在年轻代的RSet中,此时遍历这个RS,将老年代C区域中D对象引用的年轻代A中的B对象,添加到标记栈中

步骤4. 移动(Evacuation/Object Copy),遍历上面的标记栈,将栈内的所有所有的对象移动至Survivor区域(其实说是移动,本质上还是复制)

如下图所示,标记栈中记录的C/F/B对象被移动到Survivor区域中

当对象年龄超过晋升的阈值时,对象会直接移动到老年代区域,而不是Survivor区域。

收尾步骤. 剩下的就是一些收尾工作,Redirty(配合下面的并发标记),Clear CT(清理Card Table),Free CSet(清理回收集合),清空移动前的区域添加到空闲区等等,这些操作一般耗时都很短

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • G1的垃圾收集模式
  • 年轻代垃圾回收(完全年轻代GC)
  • 年轻代垃圾回收过程
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档