Skip to content

g1 G1_Refine

ceragon edited this page Dec 7, 2021 · 1 revision

G1 Refine 线程

声明

  1. 声明位于 g1ConcurrentRefineThread.cpp 中
G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint worker_id) :
                                                                        ConcurrentGCThread(){
    set_name("G1 Refine#%d", worker_id);
    create_and_start();
}
  1. 在 create_and_start 方法中会启动线程

run 方法

  1. 线程的run方法如下
void ConcurrentGCThread::run() {
  initialize_in_thread();
  wait_for_universe_init();
  run_service();
  terminate();
}
  1. run方法会调用 run_service() 方法,内容如下:
void G1ConcurrentRefineThread::run_service() {
    while (!should_terminate()) {
        wait_for_completed_buffers();
        if (should_terminate()) {
          break;
        }
        
        size_t buffers_processed = 0;
        SuspendibleThreadSetJoiner sts_join;
        while (!should_terminate()) {
            if (sts_join.should_yield()) {
              sts_join.yield();
              continue;             // Re-check for termination after yield delay.
            }
            if (!_cr->do_refinement_step(_worker_id)) {
              break;
            }
            ++buffers_processed;
        }
        deactivate();
    }
}

触发方式

  1. 上面的run_service() 方法会在 wait_for_completed_buffers() 处等待
void G1ConcurrentRefineThread::wait_for_completed_buffers() {
    MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
    while (!should_terminate() && !is_active()) {
        _monitor->wait(Mutex::_no_safepoint_check_flag);
    }
}
  1. 其中的 _monitor 会处于无限等待状态,直到被其他线程调用 _monitor -> notify() 来唤醒,唯一调用 notify() 的方法如下:
void G1ConcurrentRefineThread::activate() {
    MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
    if (!is_primary()) {
        set_active(true);
    } else {
        DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
        dcqs.set_process_completed(true);
    }
    _monitor->notify();
}
  1. 调用 activate 的方法如下:
void G1ConcurrentRefineThreadControl::maybe_activate_next(uint cur_worker_id) {
    uint worker_id = cur_worker_id + 1;
    G1ConcurrentRefineThread* thread_to_activate = _threads[worker_id];
    if (thread_to_activate != NULL && !thread_to_activate->is_active()) {
        thread_to_activate->activate();
    }
}
  1. 调用 maybe_activate_next 的方法如下:
void G1ConcurrentRefine::maybe_activate_more_threads(uint worker_id, size_t num_cur_buffers) {
    if (num_cur_buffers > activation_threshold(worker_id + 1)) {
        _thread_control.maybe_activate_next(worker_id);
    }
}
  1. 按照上面的方式继续查看
bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
    DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();

    size_t curr_buffer_num = dcqs.completed_buffers_num();
      // If the number of the buffers falls down into the yellow zone,
      // that means that the transition period after the evacuation pause has ended.
      // Since the value written to the DCQS is the same for all threads, there is no
      // need to synchronize.
    if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= yellow_zone()) {
        dcqs.set_completed_queue_padding(0);
    }

    maybe_activate_more_threads(worker_id, curr_buffer_num);

    // Process the next buffer, if there are enough left.
    return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(),
                                                       deactivation_threshold(worker_id));
}
  1. 再查看。好吧,又绕回来了,我想想这里的原理是啥。
void G1ConcurrentRefineThread::run_service() {
    while (!should_terminate()) {
        if (!_cr->do_refinement_step(_worker_id)) {
            break;
        }
    }
}

Clone this wiki locally