panda白话 - G1垃圾收集器 - Mixed GC - 初始标记(根分区扫描)源码分析

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

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(
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值