Panda白话 - G1垃圾收集器 之 Refine线程

本文详细解析了Java G1垃圾收集器中的并发Refinement线程如何处理Dirty Card Queue (DCQ)和Remember Set (RSet),涉及DCQ的管理、抽样策略与RSet更新机制,以及不同Refinement Zone的工作负载调度。

先上一张Panda总结图,欢迎大佬们指正:
在这里插入图片描述

DCQ - Dirty Catd Queue
DCQS - Dirty Catd Queue Set
Mutator - 用户线程
RSet - Remember Set
Refinement - 优化线程

图描述:

  • 每个Mutator(用户线程)私有一个DCQ,默认长度256,即可以记录256条引用记录,可以通过G1UpdateBufferSize参数修改

  • 当用户线程修改代间引用关系(O->Y,O->O)panda.kongfu = new Kongfu();,写屏障会记录该引用记录到DCQ

  • 当DCQ记录数达到阈值(256)则将DCQ加入到DCQS,mutator重新申请一个DCQ

  • Refinement线程处理DQCS中DCQ

  • DCQS所有处理引用线程共享

  • DCQS分为4个Zone:白、绿、黄、红

  • Green : Yellow : Red = 1 : 3 : 6

  • DCQS 初始化时定义了一个全局静态的Monitor,所有Mutator可以访问

  • 当DCQS使用GreenZone时,Mutator线程会notify 0号Refine线程启动处理DCQ,0号线程会notify 1号Refine,1号notify 2号。。。(最后一个Refine线程处理抽样)

  • Refine线程数可以由G1ConcRefinementThreads设置,未设置 则 = ParallelGCThreads

  • 当DCQS使用YellowZone时,所有Refine线程启动处理DCQ

  • 当DCQS使用RedZone时,Mutator线程也加入Refine工作

  • Refine线程启动处理DCQ,根据引用记录更新RSet

  • RSet随着引用数增多,切换数据结构 SparseTable(稀疏哈希表) ->PerRegionTable(细粒度PRT) ->BitMap(粗粒度位图)

整体框架脑子里有个概念了,下面开始庖丁解牛~

Refine线程:

  • G1引入的并发线程池
  • 线程数 = G1ConcRefinementThreads+1 (默认)

Refine线程的功能:

  • 处理新生代分区的抽样 - 更新YHR(Young Heap Region)的数目
  • 管理RSet

处理新生代分区的抽样:

功能: 设置YHR - 新生代分区的个数,使G1满足GC的预测停顿时间-XX:MaxGCPauseMillis

抽样方法 - 关键源码:concurrentG1RefineThread.cpp

void ConcurrentG1RefineThread::run_young_rs_sampling() {
   
   
  // 获取DCQS - 线程共享
  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
  while(!_should_terminate) {
   
   
    //采样方法
    sample_young_list_rs_lengths();
    //加锁 - 线程共享、并发
    MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
    if (_should_terminate) {
   
   
      break;
    }
    //G1ConcRefinementServiceIntervalMillis - 采样间隔时间 - 控制抽样频度
    _monitor->wait(Mutex::_no_safepoint_check_flag, G1ConcRefinementServiceIntervalMillis);
  }
}

源码关键信息:

  • 循环采样
  • 采样方法sample_young_list_rs_lengths();
  • 每次采样间隔时间G1ConcRefinementServiceIntervalMillis

继续追采样方法sample_young_list_rs_lengths():

// Refine 线程采样方法
void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
   
   
  SuspendibleThreadSetJoiner sts;
  //获取G1管理的堆空间
  G1CollectedHeap* g1h = G1CollectedHeap::heap();
  G1CollectorPolicy* g1p = g1h->g1_policy();
  if (g1p->adaptive_young_list_length()) {
   
   
    int regions_visited = 0<
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值