From c2c188f0ba6bf2a0e3e8a6840a92c7525012f2db Mon Sep 17 00:00:00 2001 From: yoa1226 Date: Wed, 23 Oct 2024 21:54:31 +0800 Subject: [PATCH] conc mark scan region root --- _posts/2024-09-05-g1-gc-young-gc-post.md | 22 +- ...024-09-15-g1-conc-mark-root-region-scan.md | 402 ++++++++++++++++++ .../conc-root-region-scan-tams.png | Bin 0 -> 62770 bytes assets/ygc-pre/note.md | 70 +++ 4 files changed, 492 insertions(+), 2 deletions(-) create mode 100644 _posts/2024-09-15-g1-conc-mark-root-region-scan.md create mode 100644 assets/conc-root-region-scan/conc-root-region-scan-tams.png diff --git a/_posts/2024-09-05-g1-gc-young-gc-post.md b/_posts/2024-09-05-g1-gc-young-gc-post.md index 2920ef6..bda408c 100644 --- a/_posts/2024-09-05-g1-gc-young-gc-post.md +++ b/_posts/2024-09-05-g1-gc-young-gc-post.md @@ -147,11 +147,29 @@ void PreservedMarks::restore() { ## ProcessEvacuationFailedRegionsTask -在 Young GC 阶段清空 markbit。 +对于在 cset 中, 还存在对象的region,看情况在 Young GC 阶段清空 mark bit。 + +```cpp +bool clear_mark_data = !g1h->collector_state()->in_concurrent_start_gc() || + g1h->policy()->should_retain_evac_failed_region(r); + +if (clear_mark_data) { + g1h->clear_bitmap_for_region(r); +} else { + // This evacuation failed region is going to be marked through. Update mark data. + cm->update_top_at_mark_start(r); + cm->set_live_bytes(r->hrm_index(), r->live_bytes()); + assert(cm->mark_bitmap()->get_next_marked_addr(r->bottom(), cm->top_at_mark_start(r)) != cm->top_at_mark_start(r), + "Marks must be on bitmap for region %u", r->hrm_index()); +} +``` ## RedirtyLoggedCardsTask -处理 dirty card 任务对象,除了在 cset 中,并且没有对象存在的 reigon 都会被处理 +处理 dirty card 任务队列,处理两类 region: + +1. 不在 cset 中。 +2. 在 cset 中,但是还有对象未移动。 ```cpp void do_card_ptr(CardValue* card_ptr) override { diff --git a/_posts/2024-09-15-g1-conc-mark-root-region-scan.md b/_posts/2024-09-15-g1-conc-mark-root-region-scan.md new file mode 100644 index 0000000..db5d751 --- /dev/null +++ b/_posts/2024-09-15-g1-conc-mark-root-region-scan.md @@ -0,0 +1,402 @@ +--- +layout: post +title: "G1 并发标记 root region scan" +date: 2024-09-15 11:00:00 +0200 +tags: [GC, G1] +--- + +前几篇文章介绍了 G1 Young GC ,从本文开始介绍 G1 并发标记。并发标记是一个非常重要的阶段,它为 Young GC(Mixed)提供数据支持。并发标记过程中大部分时间并不会暂停用户线程,只有小部分时间会暂停用户线程。 + + +## 触发并发标记 + +并发标记是根据一些数据条件,以及当时 GC 的类型来确定是否触发。 + +### IOHP + +IOHP 全称 InitiatingHeapOccupancyPercent, 使用 `-XX:InitiatingHeapOccupancyPercent=45` 指定。 + +它的意思是,当所有老年代(包括 humongous region)region 总和超过全堆 reigon 总和的 45 % 时需要触发并发标记。 + +如果指定了 `-XX:+G1UseAdaptiveIHOP` , G1 会通过一定的算法自适应计算 IHOP 的值。 + +```cpp +G1IHOPControl* G1Policy::create_ihop_control(const G1OldGenAllocationTracker* old_gen_alloc_tracker, const G1Predictions* predictor) { + if (G1UseAdaptiveIHOP) { + return new G1AdaptiveIHOPControl(InitiatingHeapOccupancyPercent, old_gen_alloc_tracker, predictor, G1ReservePercent, G1HeapWastePercent); + } else { + return new G1StaticIHOPControl(InitiatingHeapOccupancyPercent, old_gen_alloc_tracker); + } +} +``` + +### Young GC 结尾 + +在 Young GC 结尾,`record_young_collection_end` 方法会根据当前 GC 类型决定是否调用 `maybe_start_marking` 方法触发并发标记。 + +```cpp +G1YoungCollector::collect(){ + policy()->record_young_collection_end(_concurrent_operation_is_full_mark, evacuation_alloc_failed()); +} + +void G1Policy::record_young_collection_end(bool concurrent_operation_is_full_mark, bool allocation_failure) { + if (G1GCPauseTypeHelper::is_concurrent_start_pause(this_pause)) { + record_concurrent_mark_init_end(); + } else { maybe_start_marking(); } + + if (G1GCPauseTypeHelper::is_mixed_pause(this_pause)) { + // This is a mixed GC. Here we decide whether to continue doing more + // mixed GCs or not. + if (!next_gc_should_be_mixed()) { maybe_start_marking(); } + } +} +``` +> 第一个判断当前 GC 如果不是并发标记的开始阶段,就调用 `maybe_start_marking` 方法。第二个判断是否多余? + + +当 `marking_request_bytes > marking_initiating_used_threshold` 成立,并且当前 GC 是 Young Ony GC,即只回收年轻代,调用 `collector_state()->set_initiate_conc_mark_if_possible(true)` 方法设置可能需要并发标记的标志。 + +```cpp + +void G1Policy::maybe_start_marking() { + if (need_to_start_conc_mark("end of GC")) { + collector_state()->set_initiate_conc_mark_if_possible(true); + } } + +bool G1Policy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) { + if (about_to_start_mixed_phase()) { return false; } + + size_t marking_initiating_used_threshold = _ihop_control->get_conc_mark_start_threshold(); + + size_t cur_used_bytes = _g1h->non_young_capacity_bytes(); + size_t alloc_byte_size = alloc_word_size * HeapWordSize; + size_t marking_request_bytes = cur_used_bytes + alloc_byte_size; + + bool result = false; + if (marking_request_bytes > marking_initiating_used_threshold) { + result = collector_state()->in_young_only_phase(); + } + return result; } +``` + +### 大对象分配 + +大对象分配的实际,按照条件设置可能需要并发标记的标志。 + +```cpp +HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size) { + if (policy()->need_to_start_conc_mark("concurrent humongous allocation", + word_size)) { + collect(GCCause::_g1_humongous_allocation); + } +} +``` + +另外 Full GC 结尾时也会判断 + +```cpp +void G1Policy::record_full_collection_end() { + collector_state()->set_initiate_conc_mark_if_possible(need_to_start_conc_mark("end of Full GC")); +} +``` + +### 确定触发并发标记 + +在 Young GC 开始时会准确判断是否需要进行并发标记。 + +```cpp +void G1CollectedHeap::do_collection_pause_at_safepoint_helper() { + policy()->decide_on_concurrent_start_pause(); + collector.collect(); + + if (should_start_concurrent_mark_operation) { + verifier()->verify_bitmap_clear(true /* above_tams_only */); + start_concurrent_cycle(collector.concurrent_operation_is_full_mark()); + ConcurrentGCBreakpoints::notify_idle_to_active(); + } +} +``` + +如果当前时 Young Only GC 则可以进行并发标记。 + +```cpp +void G1Policy::decide_on_concurrent_start_pause() { + if (collector_state()->initiate_conc_mark_if_possible()) { + if (!about_to_start_mixed_phase() && collector_state()->in_young_only_phase()) { + initiate_conc_mark(); + }else if( + //其他情况 + initiate_conc_mark(); + ) + } +} +``` +如果本轮已经是并发标记的开始阶段,在结束时还需要判断。 + +```cpp +_concurrent_operation_is_full_mark = policy()->concurrent_operation_is_full_mark("Revise IHOP"); + +bool G1Policy::concurrent_operation_is_full_mark(const char* msg) { + return collector_state()->in_concurrent_start_gc() && + ((_g1h->gc_cause() != GCCause::_g1_humongous_allocation) || need_to_start_conc_mark(msg)); +} +``` + +最后在 `start_concurrent_cycle` 根据 `concurrent_operation_is_full_mark` 是否进行并发标记。 + +```cpp +void G1CollectedHeap::start_concurrent_cycle(bool concurrent_operation_is_full_mark) { + if (concurrent_operation_is_full_mark) { + _cm->post_concurrent_mark_start(); + _cm_thread->start_full_mark(); + } else { + _cm->post_concurrent_undo_start(); + _cm_thread->start_undo_mark(); + } + CGC_lock->notify(); +} +``` + +小结: + +- `_initiate_conc_mark_if_possible` 是在上一轮 Young GC 结束时判断是否需要设置。 +- `_in_concurrent_start_gc` 是在当前 Young GC 开始时根据上面字段和其他条件设置。 +- `concurrent_operation_is_full_mark` 是在当前 Young GC 结束时根据上面的字段和其他条件设置。 + +## Young GC + +Young GC 作为并发标记的第一个阶段,其中一些代码是为后续并发标记做准备的。 + +`G1PreConcurrentStartTask` 是准备并发标记需要的数据结构,后面使用时再详细说明。 + +```cpp +void G1YoungCollector::pre_evacuate_collection_set(G1EvacInfo* evacuation_info) { + if (collector_state()->in_concurrent_start_gc()) { + concurrent_mark()->pre_concurrent_start(_gc_cause); + } +} + +void G1ConcurrentMark::pre_concurrent_start(GCCause::Cause cause) { + G1PreConcurrentStartTask cl(cause, this); +} + +G1PreConcurrentStartTask::G1PreConcurrentStartTask(GCCause::Cause cause, G1ConcurrentMark* cm) : + add_serial_task(new ResetMarkingStateTask(cm)); + add_parallel_task(new NoteStartOfMarkTask());{} +``` + +在 GC root 遍历时行标记对象。 + +```cpp +if (g1h->collector_state()->in_concurrent_start_gc()) { + res = new G1ConcurrentStartMarkClosures(g1h, pss); +} + +template +class G1ConcurrentStartMarkClosures : public G1EvacuationRootClosures { + G1SharedClosures _strong; +} + +void G1ParCopyClosure::do_oop_work(T* p) { + if (should_mark) { + mark_object(obj); + } +} +``` + +对象复制阶段,当 survivor 或者 old 空间耗尽时,会加入到 `root_region` 中。 + +```cpp +void G1CollectedHeap::retire_gc_alloc_region(G1HeapRegion* alloc_region, + size_t allocated_bytes, + G1HeapRegionAttr dest) { + bool const during_im = collector_state()->in_concurrent_start_gc(); + if (during_im && allocated_bytes > 0) { + _cm->add_root_region(alloc_region); + } +} +``` + +Young GC 结尾阶段将 cset 候选 region 加入到 `root_region`。 + +```cpp +void G1YoungCollector::post_evacuate_collection_set(.....) { + if (collector_state()->in_concurrent_start_gc()) { + enqueue_candidates_as_root_regions(); + } +} +``` + +## 并发标记启动 + +在 `post_concurrent_mark_start` 方法做一些准备,然后调用 ` CGC_lock->notify()` 唤醒 `G1ConcurrentMarkThread` 线程。 + +```cpp +//start_concurrent_cycle(collector.concurrent_operation_is_full_mark()); + +void G1CollectedHeap::start_concurrent_cycle(bool concurrent_operation_is_full_mark) { + assert(!_cm_thread->in_progress(), "Can not start concurrent operation while in progress"); + + MutexLocker x(CGC_lock, Mutex::_no_safepoint_check_flag); + if (concurrent_operation_is_full_mark) { + _cm->post_concurrent_mark_start(); + _cm_thread->start_full_mark(); + } else { /* YGC 完成之后,不需要并发提前退出 */ } + CGC_lock->notify(); +} + +void G1ConcurrentMark::post_concurrent_mark_start() { + + SATBMarkQueueSet& satb_mq_set = G1BarrierSet::satb_mark_queue_set(); + satb_mq_set.set_active_all_threads(true, /* new active value */ false /* expected_active */); + _root_regions.prepare_for_scan(); +} + +void G1ConcurrentMarkThread::run_service() { + while (wait_for_next_cycle()) { + concurrent_cycle_start(); + if (_state == FullMark) { + concurrent_mark_cycle_do(); + } else { concurrent_undo_cycle_do(); } + concurrent_cycle_end(_state == FullMark && !_cm->has_aborted()); + } + _cm->root_regions()->cancel_scan(); +} + +bool G1ConcurrentMarkThread::wait_for_next_cycle() { + MonitorLocker ml(CGC_lock, Mutex::_no_safepoint_check_flag); + while (!in_progress() && !should_terminate()) { + ml.wait(); + } + return !should_terminate(); +} +``` + +如上所示, `G1ConcurrentMarkThread` 阻塞在 `CGC_lock` 上。 + +下面代码是并发标记的整体逻辑,其中 `phase_scan_root_regions` 是本文接下来的内容,并且此阶段结束之前不能被打断。 + +```cpp +void G1ConcurrentMarkThread::concurrent_mark_cycle_do() { + HandleMark hm(Thread::current()); + ResourceMark rm; + + // Phase 1: Scan root regions. + if (phase_scan_root_regions()) return; + + // Phase 2: Actual mark loop. + if (phase_mark_loop()) return; + + // Phase 3: Rebuild remembered sets and scrub dead objects. + if (phase_rebuild_and_scrub()) return; + + // Phase 4: Wait for Cleanup. + if (phase_delay_to_keep_mmu_before_cleanup()) return; + + // Phase 5: Cleanup pause + if (phase_cleanup()) return; + + // Phase 6: Clear CLD claimed marks. + if (phase_clear_cld_claimed_marks()) return; + + // Phase 7: Clear bitmap for next mark. + phase_clear_bitmap_for_next_mark(); +} +``` + +> G1 makes sure that this concurrent phase has been completed before the next GC, at worst delaying start of the next garbage collection until completed. If G1 did not do that, there would be problems with objects not surviving that next GC wrt to SATB. + +Young GC 等待 root region scan 完成。 + +```cpp +void G1YoungCollector::collect() { + wait_for_root_region_scanning(); +} +``` + +## TAMS + +在 region 中有三个字段: +- _bottom 指向 region 起始位置。 +- _end 指向 region 结束为止。 +- _top 指向目前待分配的位置。 + +```cpp +class G1HeapRegion : public CHeapObj { + HeapWord* const _bottom; + HeapWord* const _end; + HeapWord* volatile _top; +} +``` + +`TAMS` 全称 `top at mark start`, 记录了 top 在并发标记前的位置。 TAMS 被记录并发满足三个条件: + +1. 是 old region 或者 humongous region。 +2. region 不在 cset中。 +3. 2. region 不在 cset 候选中。 + +对于在这里没有显示设置 TAMS 位置的 reigon,其 TAMS 值等于其 bottom。 + +```cpp +//pre_evacuate_collection_set->G1ConcurrentMark::pre_concurrent_start +//G1PreConcurrentStartTask cl(cause, this); +void G1PreConcurrentStartTask::NoteStartOfMarkTask::do_work(uint worker_id) { + NoteStartOfMarkHRClosure start_cl; + G1CollectedHeap::heap()->heap_region_par_iterate_from_worker_offset(&start_cl, &_claimer, worker_id); +} + +class NoteStartOfMarkHRClosure : public G1HeapRegionClosure { + G1ConcurrentMark* _cm; + + bool do_heap_region(G1HeapRegion* r) override { + if (r->is_old_or_humongous() && !r->is_collection_set_candidate() && !r->in_collection_set()) { + _cm->update_top_at_mark_start(r); + } + return false; } +} + +inline void G1ConcurrentMark::update_top_at_mark_start(G1HeapRegion* r) { + uint const region = r->hrm_index(); + _top_at_mark_starts[region] = r->top(); +} + +``` + +如下图,有三个 region,属性在 young GC 收集前和收集后的变化。 + + + +tams 与 top 之间的区域是本次 young gc 存活下来的对象,这些对象明确为活对象,这些区域会作为 root region。 + +```cpp +void G1ConcurrentMark::add_root_region(G1HeapRegion* r) { + root_regions()->add(top_at_mark_start(r), r->top()); +} +void G1CMRootMemRegions::add(HeapWord* start, HeapWord* end) { + size_t idx = Atomic::fetch_then_add(&_num_root_regions, 1u); + _root_regions[idx].set_start(start); + _root_regions[idx].set_end(end); +} +``` + +## root region scan + + + + + + + + + + + + + + + + + + + + diff --git a/assets/conc-root-region-scan/conc-root-region-scan-tams.png b/assets/conc-root-region-scan/conc-root-region-scan-tams.png new file mode 100644 index 0000000000000000000000000000000000000000..c5a7d778aa96e75d1e131be332e3d67027125e3f GIT binary patch literal 62770 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 VROD=Oixm%G_Vl^aGUVU>@Sh~q7!Lpd literal 0 HcmV?d00001 diff --git a/assets/ygc-pre/note.md b/assets/ygc-pre/note.md index bb56dfc..212816b 100644 --- a/assets/ygc-pre/note.md +++ b/assets/ygc-pre/note.md @@ -33,3 +33,73 @@ void G1CollectedHeap::retire_gc_alloc_region(G1HeapRegion* alloc_region, size_t https://github.com/yoa1226/yoa1226.github.io + +```cpp +bool G1Policy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) { + if (about_to_start_mixed_phase()) { + return false; + } + + size_t marking_initiating_used_threshold = _ihop_control->get_conc_mark_start_threshold(); + + size_t cur_used_bytes = _g1h->non_young_capacity_bytes(); + size_t alloc_byte_size = alloc_word_size * HeapWordSize; + size_t marking_request_bytes = cur_used_bytes + alloc_byte_size; + + bool result = false; + if (marking_request_bytes > marking_initiating_used_threshold) { + result = collector_state()->in_young_only_phase(); + log_debug(gc, ergo, ihop)("%s occupancy: " SIZE_FORMAT "B allocation request: " SIZE_FORMAT "B threshold: " SIZE_FORMAT "B (%1.2f) source: %s", + result ? "Request concurrent cycle initiation (occupancy higher than threshold)" : "Do not request concurrent cycle initiation (still doing mixed collections)", + cur_used_bytes, alloc_byte_size, marking_initiating_used_threshold, (double) marking_initiating_used_threshold / _g1h->capacity() * 100, source); + } + return result; +} + +void G1Policy::maybe_start_marking() { + if (need_to_start_conc_mark("end of GC")) { + // Note: this might have already been set, if during the last + // pause we decided to start a cycle but at the beginning of + // this pause we decided to postpone it. That's OK. + collector_state()->set_initiate_conc_mark_if_possible(true); + } +} + + +bool const during_im = collector_state()->in_concurrent_start_gc(); + if (during_im && allocated_bytes > 0) { + _cm->add_root_region(alloc_region); + } + + G1EvacuationRootClosures* res = nullptr; +if (g1h->collector_state()->in_concurrent_start_gc()) { + if (ClassUnloadingWithConcurrentMark) { + res = new G1ConcurrentStartMarkClosures(g1h, pss); + } else { + res = new G1ConcurrentStartMarkClosures(g1h, pss); + } +} else { + res = new G1EvacuationClosures(g1h, pss, process_only_dirty_klasses); +} + + + if (collector_state()->in_concurrent_start_gc()) { + concurrent_mark()->pre_concurrent_start(_gc_cause); + } + + + void G1YoungCollector::enqueue_candidates_as_root_regions() { + assert(collector_state()->in_concurrent_start_gc(), "must be"); + + G1CollectionSetCandidates* candidates = collection_set()->candidates(); + for (G1HeapRegion* r : *candidates) { + _g1h->concurrent_mark()->add_root_region(r); + } +} + + EagerlyReclaimHumongousObjectsTask() + //处理大对象 + + +``` +