G1垃圾收集 - Mixed GC:
- 初始标记阶段 - Initial Mark
- 并发标记阶段 - Concurrent Mark
- 最终标记阶段 - Remark
- 清理阶段 - Clean Up
初始标记阶段 - Initial Mark - 根标记
特性:
- STW
- 以Young GC后的survivor分区作为根进行扫描
- 扫描的是survivor 分区到老年代Region对象的引用
- 所以Mixed GC 一定发生在Young GC 之后
根分区扫描步骤:
scanRootRegions扫描所有survivor分区scanRootRegion逐个region进行扫描处理- [bootom, top]区间内所有的对象
grayRoot置灰 - 置灰就是在NextBitMap位图中进行标记、统计存活对象大小
结果:
- 将survivor region 中所有对象标记为根(置为灰色)
- 扫描survivor region中
- 所有指向老年代的
- 在Young GC初始标记阶段标记的引用
- 及引用指向的对象
扫描指向老年代的引用 - 理解:
RSet 只记录 O->Y (老年代到年轻代的引用) O->O(老年代到老年代的引用)详情请看这篇 ->>>>>Panda 白话 - G1垃圾收集器 之 RSet(Remembed Set)源码解读
所以针对老年代被年轻代引用的对象,在一次young GC中,存活对象会被复制到Survivor Region
所以需要扫描Survivor 分区的对象,作为根,来找到老年代被年轻代引用的对象,即存活对象
源码分析:
根分区扫描源码在:concurrentMark.cpp
void ConcurrentMark::scanRootRegions() {
ClassLoaderDataGraph::clear_claimed_marks();
//至少有一个分区需要扫描时,scan_in_progress会被设置为true
//这里root_regions获取的是survivor分区
if (root_regions()->scan_in_progress()) {
//获取并行标记线程数
_parallel_marking_threads = calc_parallel_marking_threads();
//标记线程数与1U取最大值
uint active_workers = MAX2(1U, parallel_marking_threads());
//创建并运行扫描任务
CMRootRegionScanTask task(this);
if (use_parallel_marking_threads(

本文详细剖析了G1垃圾收集器中的Mixed GC过程,重点讲解了初始标记阶段的根分区扫描,从survivor分区出发,扫描老年代引用,确保并发标记的准确性。通过源码分析,揭示了置灰操作和并发计数的重要性。
最低0.47元/天 解锁文章
1425

被折叠的 条评论
为什么被折叠?



