G1垃圾回收器与分代回收结合理解

G1垃圾回收器将堆内存划分为region,并通过并发标记维护一个优先级列表,识别“死鬼聚集地”和“活人聚集地”。它在年轻代和老年代的管理上结合分代回收思想,主要通过MixedGC进行垃圾回收,该过程包括初始标记、并发标记、最终标记和筛选回收四个步骤。G1在达到一定阈值时执行MixedGC,但年轻代的垃圾回收(YoungGC/MiningGC)也会辅助这一过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先G1垃圾回收器和分代回收是从不同角度看待垃圾回收

分代回收是根据对象的特点分为新生代(低情商:早死鬼),老年代(低情商:老不死的东西)

G1垃圾回收器是根据对象存放的区域进行划分:死鬼聚集地 和 活人聚集地(注意,这里不能理解成分类,只是对区域垃圾不同程度的称呼,就像每个男人都好色,但只有最好色的那一批人才被称为色魔)

这两种角度互不冲突,可以相互进行结合

而对这两种角度进行结合的回收器就是G1垃圾回收器

分代回收的思想是怎么样的,我上一篇文章已经讲过了。这里不在赘述

这里重点讲讲:G1的分区域思想是如何实现的 ,以及这份思想如何与分代回收结合的

1,分区域思想的实现:

       首先G1回收器将堆内存划分为一块块region,然后我们需要判断那些区域是“死鬼聚集地”,那些是“活人聚集地”, G1回收器内部维护了一个优先级列表

优先级越高的地方越“死鬼”。 G1根据用户制定的参数消灭一些死鬼聚集地,

这里你可能会有疑问G1是如何维护这个优先级列表呢?它是如何知道一个region内死鬼的多少呢?

答:通过并发标记(下文在讲)

2,如何把分代和分区域结合起来:

这里我们直接来看G1回收器的工作流程就懂了:

大部分书会直接讲Mixed GC部分,但那不是G1回收的全部

 

 这里的youngGC其实就是minorGC换了个马甲,因为G1分区域了,导致实现上有些不一样,但实际上还是那一套。

我们看到G1大部分时间可能还是在youngGC处理新生代,而不是一直在MixedGC,它只有达到

InitiatingHeapOccupancyPercent

这个标准才会MixedGC(实际上不是严格意义上MixedGC,但这里这样理解是可以的,之后会解释)  这个InitiatingHeapOccupancyPercent参数有很多文章所示老年代占堆内存的大小

但官方给的定义是

设置触发标记周期的 Java 堆占用阈值。默认占用是整个 Java 堆的 45%。

详细可查https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html

我们再来讲讲这里的MixedGC部分是如何实现的:

我们看到MixedGC的主要分为四个步骤:

1,初始标记:简单标记一下与GCRoot直接关联的对象

2,并发标记:对GCRoot开始堆中对象进行可达性分析,扫描整个堆的对象图(这样哪里有多少垃圾不就一目了然吗,通过这一步维护优先级列表)。 

3,最终标记:处理并发标记阶段遗留下的少量SATB记录。(这部分属于SATB算法的知识,看不懂没关系)

4,筛选回收:更新一下优先级列表(毕竟最终标记部分可能有修改)根据优先级列表 处理垃圾区域 处理方式是:把垃圾区域中存活对象复制放到空的region中,把原来的垃圾region清空。

但实际上:初始标记阶段可以由YoungGC来顺手完成不是吗?

 所以我之前说的到阈值才进行 MixedGC实际上是不严谨的,某种意义上YoungGC就已经开始MixedGC了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值