Repository navigation
g1 G1_Refine
ceragon edited this page Dec 7, 2021
·
1 revision
- 声明位于 g1ConcurrentRefineThread.cpp 中
G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint worker_id) :
ConcurrentGCThread(){
set_name("G1 Refine#%d", worker_id);
create_and_start();
}- 在 create_and_start 方法中会启动线程
- 线程的run方法如下
void ConcurrentGCThread::run() {
initialize_in_thread();
wait_for_universe_init();
run_service();
terminate();
}- 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();
}
}- 上面的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);
}
}- 其中的 _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();
}- 调用 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();
}
}- 调用 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);
}
}
- 按照上面的方式继续查看
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));
}- 再查看。好吧,又绕回来了,我想想这里的原理是啥。
void G1ConcurrentRefineThread::run_service() {
while (!should_terminate()) {
if (!_cr->do_refinement_step(_worker_id)) {
break;
}
}
}