Skip to content

g1 mark GC_Pause

ceragon edited this page Dec 18, 2021 · 1 revision

GC Pause 触发标记

触发流程

  1. GC Pause 的执行方法,上部分是类的说明,下部分是方法的执行主体
class VM_G1CollectForAllocation: public VM_CollectForAllocation : : public VM_GC_Operation: public VM_Operation{
    // 所有继承自 VM_Operation 的类都是在 VM Thread 中执行
    // 该类的对象一旦被 VM Thread 开始执行,会先申请 STW
    // 等 STW 成功后,会执行 doit() 方法
    private:
        // 在构造函数中赋值
        bool      _should_initiate_conc_mark;
    protected:
        // 在构造函数中赋值
        size_t    _word_size;
}
void VM_G1CollectForAllocation::doit() {
    if (_word_size > 0) {
        _result = g1h->attempt_allocation_at_safepoint(_word_size, false);
        if (_result != NULL) {
            _pause_succeeded = true;
            return;
        }
    }
    if (_should_initiate_conc_mark) {
        bool res = g1h->g1_policy()->force_initial_mark_if_outside_cycle(_gc_cause);
        if (!res) {
            return;
        }
    }
    // 在安全点执行 GC 的回收方法,同时会在满足条件后间接调用启动标记循环的方法 do_concurrent_mark()
    _pause_succeeded = g1h->do_collection_pause_at_safepoint(_target_pause_time_ms);
}
  1. 上面提到了 VM Thread。VM_G1CollectForAllocation 类的构造罗列如下,会重点关注 _word_size 和 _should_initiate_conc_mark 两个值的传参
void G1CollectedHeap::collect(GCCause::Cause cause) {
    if (should_do_concurrent_full_gc(cause)) {
        VM_G1CollectForAllocation op(0,     /* word_size */
                                   gc_count_before,
                                   cause,
                                   true,  /* should_initiate_conc_mark */
                                   g1_policy()->max_pause_time_ms());
        VMThread::execute(&op);
    } else if (GCLocker::should_discard(cause, gc_count_before)) {
        return;
    } else {
        if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc) {
            VM_G1CollectForAllocation op(0,     /* word_size */
                                     gc_count_before,
                                     cause,
                                     false, /* should_initiate_conc_mark */
                                     g1_policy()->max_pause_time_ms());
            VMThread::execute(&op);
        }
    }
    
}
HeapWord* G1CollectedHeap::do_collection_pause(size_t word_size, uint gc_count_before, bool* succeeded, GCCause::Cause gc_cause) {
    VM_G1CollectForAllocation op(word_size,  /* word_size */
                               gc_count_before,
                               gc_cause,
                               false, /* should_initiate_conc_mark */
                               g1_policy()->max_pause_time_ms());
    VMThread::execute(&op);
}

Clone this wiki locally