diff --git a/src/hotspot/share/gc/g1/g1CardSet.cpp b/src/hotspot/share/gc/g1/g1CardSet.cpp index 7ab739e0196..5c11a1a9677 100644 --- a/src/hotspot/share/gc/g1/g1CardSet.cpp +++ b/src/hotspot/share/gc/g1/g1CardSet.cpp @@ -244,6 +244,10 @@ class G1CardSetHashTable : public CHeapObj { using CHTScanTask = CardSetHash::ScanTask; const static uint BucketClaimSize = 16; + // The claim size for group cardsets should be smaller to facilitate + // better work distribution. The group cardsets should be larger than + // the per region cardsets. + const static uint GroupBucketClaimSize = 4; // Did we insert at least one card in the table? bool volatile _inserted_card; @@ -347,7 +351,15 @@ public: } void reset_table_scanner() { - _table_scanner.set(&_table, BucketClaimSize); + reset_table_scanner(BucketClaimSize); + } + + void reset_table_scanner_for_groups() { + reset_table_scanner(GroupBucketClaimSize); + } + + void reset_table_scanner(uint claim_size) { + _table_scanner.set(&_table, claim_size); } void grow() { @@ -1042,3 +1054,7 @@ void G1CardSet::clear() { void G1CardSet::reset_table_scanner() { _table->reset_table_scanner(); } + +void G1CardSet::reset_table_scanner_for_groups() { + _table->reset_table_scanner_for_groups(); +} diff --git a/src/hotspot/share/gc/g1/g1CardSet.hpp b/src/hotspot/share/gc/g1/g1CardSet.hpp index a9f1859d5c7..22530ddadaf 100644 --- a/src/hotspot/share/gc/g1/g1CardSet.hpp +++ b/src/hotspot/share/gc/g1/g1CardSet.hpp @@ -380,6 +380,8 @@ public: void reset_table_scanner(); + void reset_table_scanner_for_groups(); + // Iterate over the container, calling a method on every card or card range contained // in the card container. // For every container, first calls diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index aa99fbecbee..fd73b725a12 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1159,6 +1159,8 @@ G1CollectedHeap::G1CollectedHeap() : _rem_set(nullptr), _card_set_config(), _card_set_freelist_pool(G1CardSetConfiguration::num_mem_object_types()), + _young_regions_cardset_mm(card_set_config(), card_set_freelist_pool()), + _young_regions_cardset(card_set_config(), &_young_regions_cardset_mm), _cm(nullptr), _cm_thread(nullptr), _cr(nullptr), @@ -2693,6 +2695,7 @@ bool G1CollectedHeap::is_old_gc_alloc_region(G1HeapRegion* hr) { void G1CollectedHeap::set_region_short_lived_locked(G1HeapRegion* hr) { _eden.add(hr); _policy->set_region_eden(hr); + hr->install_group_cardset(young_regions_cardset()); } #ifdef ASSERT @@ -2902,6 +2905,8 @@ G1HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size, G1HeapRegio new_alloc_region->set_survivor(); _survivor.add(new_alloc_region); register_new_survivor_region_with_region_attr(new_alloc_region); + // Install the group cardset. + new_alloc_region->install_group_cardset(young_regions_cardset()); } else { new_alloc_region->set_old(); } @@ -3043,3 +3048,7 @@ void G1CollectedHeap::finish_codecache_marking_cycle() { CodeCache::on_gc_marking_cycle_finish(); CodeCache::arm_all_nmethods(); } + +void G1CollectedHeap::prepare_group_cardsets_for_scan () { + _young_regions_cardset.reset_table_scanner_for_groups(); +} diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index ea087aae662..0f8bf9ffd2b 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -779,7 +779,19 @@ private: G1MonotonicArenaFreePool _card_set_freelist_pool; + // Group cardsets + G1CardSetMemoryManager _young_regions_cardset_mm; + G1CardSet _young_regions_cardset; + public: + G1CardSetConfiguration* card_set_config() { return &_card_set_config; } + + G1CardSet* young_regions_cardset() { return &_young_regions_cardset; }; + + G1CardSetMemoryManager* young_regions_card_set_mm() { return &_young_regions_cardset_mm; } + + void prepare_group_cardsets_for_scan(); + // After a collection pause, reset eden and the collection set. void clear_eden(); void clear_collection_set(); diff --git a/src/hotspot/share/gc/g1/g1CollectionSet.cpp b/src/hotspot/share/gc/g1/g1CollectionSet.cpp index fe4dfafee97..d315497268f 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSet.cpp +++ b/src/hotspot/share/gc/g1/g1CollectionSet.cpp @@ -297,7 +297,7 @@ double G1CollectionSet::finalize_young_part(double target_pause_time_ms, G1Survi verify_young_cset_indices(); - double predicted_base_time_ms = _policy->predict_base_time_ms(pending_cards); + double predicted_base_time_ms = _policy->predict_base_time_ms(pending_cards, _g1h->young_regions_cardset()->occupied()); // Base time already includes the whole remembered set related time, so do not add that here // again. double predicted_eden_time = _policy->predict_young_region_other_time_ms(eden_region_length) + diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index 3d56973299e..52d26418af6 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -2980,6 +2980,7 @@ G1PrintRegionLivenessInfoClosure::G1PrintRegionLivenessInfoClosure(const char* p _total_capacity_bytes(0), _total_live_bytes(0), _total_remset_bytes(0), + _young_cardset_bytes_per_region(0), _total_code_roots_bytes(0) { if (!log_is_enabled(Trace, gc, liveness)) { @@ -2990,6 +2991,13 @@ G1PrintRegionLivenessInfoClosure::G1PrintRegionLivenessInfoClosure(const char* p MemRegion reserved = g1h->reserved(); double now = os::elapsedTime(); + uint num_young_regions = g1h->young_regions_count(); + size_t young_cardset_bytes = g1h->young_regions_cardset()->mem_size(); + + if (num_young_regions > 0) { + _young_cardset_bytes_per_region = young_cardset_bytes / num_young_regions; + } + // Print the header of the output. log_trace(gc, liveness)(G1PPRL_LINE_PREFIX" PHASE %s @ %1.3f", phase_name, now); log_trace(gc, liveness)(G1PPRL_LINE_PREFIX" HEAP" @@ -3041,6 +3049,10 @@ bool G1PrintRegionLivenessInfoClosure::do_heap_region(G1HeapRegion* r) { const char* remset_type = r->rem_set()->get_short_state_str(); FormatBuffer<16> gc_efficiency(""); + if (r->is_young()) { + remset_bytes = _young_cardset_bytes_per_region; + } + _total_used_bytes += used_bytes; _total_capacity_bytes += capacity_bytes; _total_live_bytes += live_bytes; diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp index 918384372bb..b197afc65ee 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -958,6 +958,8 @@ class G1PrintRegionLivenessInfoClosure : public G1HeapRegionClosure { // Accumulator for the remembered set size size_t _total_remset_bytes; + size_t _young_cardset_bytes_per_region; + // Accumulator for code roots memory size size_t _total_code_roots_bytes; diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp index 7d6cc9a41cb..8357737ef6a 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp @@ -254,21 +254,18 @@ uint64_t G1ConcurrentRefine::adjust_threads_wait_ms() const { } class G1ConcurrentRefine::RemSetSamplingClosure : public G1HeapRegionClosure { - size_t _sampled_card_rs_length; size_t _sampled_code_root_rs_length; public: RemSetSamplingClosure() : - _sampled_card_rs_length(0), _sampled_code_root_rs_length(0) {} + _sampled_code_root_rs_length(0) {} bool do_heap_region(G1HeapRegion* r) override { G1HeapRegionRemSet* rem_set = r->rem_set(); - _sampled_card_rs_length += rem_set->occupied(); _sampled_code_root_rs_length += rem_set->code_roots_list_length(); return false; } - size_t sampled_card_rs_length() const { return _sampled_card_rs_length; } size_t sampled_code_root_rs_length() const { return _sampled_code_root_rs_length; } }; @@ -286,10 +283,15 @@ public: // gen size to keep pause time length goal. void G1ConcurrentRefine::adjust_young_list_target_length() { if (_policy->use_adaptive_young_list_length()) { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + G1CollectionSet* cset = g1h->collection_set(); RemSetSamplingClosure cl; - G1CollectionSet* cset = G1CollectedHeap::heap()->collection_set(); cset->iterate(&cl); - _policy->revise_young_list_target_length(cl.sampled_card_rs_length(), cl.sampled_code_root_rs_length()); + + size_t card_rs_length = g1h->young_regions_cardset()->occupied(); + + size_t sampled_code_root_rs_length = cl.sampled_code_root_rs_length(); + _policy->revise_young_list_target_length(card_rs_length, sampled_code_root_rs_length); } } diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 219480227d3..4c66c526151 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -172,6 +172,7 @@ public: bool do_heap_region(G1HeapRegion* hr) { hr->prepare_for_full_gc(); + hr->uninstall_group_cardset(); G1CollectedHeap::heap()->prepare_region_for_full_compaction(hr); _collector->before_marking_update_attribute_table(hr); return false; @@ -247,6 +248,8 @@ void G1FullCollector::complete_collection() { _heap->resize_all_tlabs(); + _heap->young_regions_cardset()->clear(); + _heap->policy()->record_full_collection_end(); _heap->gc_epilogue(true); diff --git a/src/hotspot/share/gc/g1/g1HeapRegion.cpp b/src/hotspot/share/gc/g1/g1HeapRegion.cpp index 9851b1df9c9..9cb2650f820 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegion.cpp +++ b/src/hotspot/share/gc/g1/g1HeapRegion.cpp @@ -119,6 +119,7 @@ void G1HeapRegion::hr_clear(bool clear_space) { clear_young_index_in_cset(); clear_index_in_opt_cset(); uninstall_surv_rate_group(); + uninstall_group_cardset(); set_free(); reset_pre_dummy_top(); @@ -215,6 +216,9 @@ void G1HeapRegion::clear_humongous() { } void G1HeapRegion::prepare_remset_for_scan() { + if (is_young()) { + uninstall_group_cardset(); + } _rem_set->reset_table_scanner(); } diff --git a/src/hotspot/share/gc/g1/g1HeapRegion.hpp b/src/hotspot/share/gc/g1/g1HeapRegion.hpp index ed953094a67..c17183d4034 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegion.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegion.hpp @@ -36,6 +36,7 @@ #include "runtime/mutex.hpp" #include "utilities/macros.hpp" +class G1CardSet; class G1CardSetConfiguration; class G1CollectedHeap; class G1CMBitMap; @@ -508,6 +509,9 @@ public: void install_surv_rate_group(G1SurvRateGroup* surv_rate_group); void uninstall_surv_rate_group(); + void install_group_cardset(G1CardSet* group_cardset); + void uninstall_group_cardset(); + void record_surv_words_in_group(size_t words_survived); // Determine if an address is in the parsable or the to-be-scrubbed area. diff --git a/src/hotspot/share/gc/g1/g1HeapRegion.inline.hpp b/src/hotspot/share/gc/g1/g1HeapRegion.inline.hpp index f31c5fb553e..4a87c5f2514 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegion.inline.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegion.inline.hpp @@ -511,4 +511,12 @@ inline void G1HeapRegion::add_pinned_object_count(size_t value) { Atomic::add(&_pinned_object_count, value, memory_order_relaxed); } +inline void G1HeapRegion::install_group_cardset(G1CardSet* group_cardset) { + _rem_set->install_group_cardset(group_cardset); +} + +inline void G1HeapRegion::uninstall_group_cardset() { + _rem_set->uninstall_group_cardset(); +} + #endif // SHARE_GC_G1_G1HEAPREGION_INLINE_HPP diff --git a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.cpp b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.cpp index 6e98b64adbc..fe1590b94a8 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.cpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.cpp @@ -55,11 +55,19 @@ void G1HeapRegionRemSet::initialize(MemRegion reserved) { _heap_base_address = reserved.start(); } +void G1HeapRegionRemSet::uninstall_group_cardset() { + if (_saved_card_set != nullptr) { + _card_set = _saved_card_set; + _saved_card_set = nullptr; + } +} + G1HeapRegionRemSet::G1HeapRegionRemSet(G1HeapRegion* hr, G1CardSetConfiguration* config) : _code_roots(), _card_set_mm(config, G1CollectedHeap::heap()->card_set_freelist_pool()), - _card_set(config, &_card_set_mm), + _card_set(new G1CardSet(config, &_card_set_mm)), + _saved_card_set(nullptr), _hr(hr), _state(Untracked) { } @@ -68,11 +76,12 @@ void G1HeapRegionRemSet::clear_fcc() { } void G1HeapRegionRemSet::clear(bool only_cardset, bool keep_tracked) { + assert(_saved_card_set == nullptr, "pre-condition"); if (!only_cardset) { _code_roots.clear(); } clear_fcc(); - _card_set.clear(); + _card_set->clear(); if (!keep_tracked) { set_state_untracked(); } else { @@ -83,7 +92,7 @@ void G1HeapRegionRemSet::clear(bool only_cardset, bool keep_tracked) { void G1HeapRegionRemSet::reset_table_scanner() { _code_roots.reset_table_scanner(); - _card_set.reset_table_scanner(); + _card_set->reset_table_scanner(); } G1MonotonicArenaMemoryStats G1HeapRegionRemSet::card_set_memory_stats() const { diff --git a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.hpp b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.hpp index e92ecdc9cf9..843eb76bbc9 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.hpp @@ -47,7 +47,8 @@ class G1HeapRegionRemSet : public CHeapObj { G1CardSetMemoryManager _card_set_mm; // The set of cards in the Java heap - G1CardSet _card_set; + G1CardSet* _card_set; + G1CardSet* _saved_card_set; G1HeapRegion* _hr; @@ -58,9 +59,24 @@ class G1HeapRegionRemSet : public CHeapObj { public: G1HeapRegionRemSet(G1HeapRegion* hr, G1CardSetConfiguration* config); + ~G1HeapRegionRemSet() { delete _card_set; } bool cardset_is_empty() const { - return _card_set.is_empty(); + return _card_set->is_empty(); + } + + void install_group_cardset(G1CardSet* group_cardset) { + assert(group_cardset != nullptr, "pre-condition"); + assert(_saved_card_set == nullptr, "pre-condition"); + + _saved_card_set = _card_set; + _card_set = group_cardset; + } + + void uninstall_group_cardset(); + + bool has_group_cardset() { + return _saved_card_set != nullptr; } bool is_empty() const { @@ -68,7 +84,7 @@ public: } bool occupancy_less_or_equal_than(size_t occ) const { - return (code_roots_list_length() == 0) && _card_set.occupancy_less_or_equal_to(occ); + return (code_roots_list_length() == 0) && _card_set->occupancy_less_or_equal_to(occ); } // Iterate the card based remembered set for merging them into the card table. @@ -77,10 +93,15 @@ public: template inline void iterate_for_merge(CardOrRangeVisitor& cl); + template + inline static void iterate_for_merge(G1CardSet* card_set, CardOrRangeVisitor& cl); + size_t occupied() { - return _card_set.occupied(); + return _card_set->occupied(); } + G1CardSet* card_set() { return _card_set; } + static void initialize(MemRegion reserved); // Coarsening statistics since VM start. @@ -125,13 +146,13 @@ public: // The actual # of bytes this hr_remset takes up. Also includes the code // root set. size_t mem_size() { - return _card_set.mem_size() + return _card_set->mem_size() + (sizeof(G1HeapRegionRemSet) - sizeof(G1CardSet)) // Avoid double-counting G1CardSet. + code_roots_mem_size(); } size_t unused_mem_size() { - return _card_set.unused_mem_size(); + return _card_set->unused_mem_size(); } // Returns the memory occupancy of all static data structures associated diff --git a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.inline.hpp b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.inline.hpp index 457027ad126..0df9874e9dd 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionRemSet.inline.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionRemSet.inline.hpp @@ -108,13 +108,17 @@ public: template inline void G1HeapRegionRemSet::iterate_for_merge(CardOrRangeVisitor& cl) { - G1HeapRegionRemSetMergeCardClosure cl2(&_card_set, - cl, - _card_set.config()->log2_card_regions_per_heap_region(), - _card_set.config()->log2_cards_per_card_region()); - _card_set.iterate_containers(&cl2, true /* at_safepoint */); + iterate_for_merge(_card_set, cl); } +template +void G1HeapRegionRemSet::iterate_for_merge(G1CardSet* card_set, CardOrRangeVisitor& cl) { + G1HeapRegionRemSetMergeCardClosure cl2(card_set, + cl, + card_set->config()->log2_card_regions_per_heap_region(), + card_set->config()->log2_cards_per_card_region()); + card_set->iterate_containers(&cl2, true /* at_safepoint */); +} uintptr_t G1HeapRegionRemSet::to_card(OopOrNarrowOopStar from) const { return pointer_delta(from, _heap_base_address, 1) >> CardTable::card_shift(); @@ -130,18 +134,18 @@ void G1HeapRegionRemSet::add_reference(OopOrNarrowOopStar from, uint tid) { // We can't check whether the card is in the remembered set - the card container // may be coarsened just now. //assert(contains_reference(from), "We just found " PTR_FORMAT " in the FromCardCache", p2i(from)); - return; + return; } - _card_set.add_card(to_card(from)); + _card_set->add_card(to_card(from)); } bool G1HeapRegionRemSet::contains_reference(OopOrNarrowOopStar from) { - return _card_set.contains_card(to_card(from)); + return _card_set->contains_card(to_card(from)); } void G1HeapRegionRemSet::print_info(outputStream* st, OopOrNarrowOopStar from) { - _card_set.print_info(st, to_card(from)); + _card_set->print_info(st, to_card(from)); } #endif // SHARE_VM_GC_G1_G1HEAPREGIONREMSET_INLINE_HPP diff --git a/src/hotspot/share/gc/g1/g1Policy.cpp b/src/hotspot/share/gc/g1/g1Policy.cpp index 7d0acd3a326..e7e57c962c7 100644 --- a/src/hotspot/share/gc/g1/g1Policy.cpp +++ b/src/hotspot/share/gc/g1/g1Policy.cpp @@ -1089,6 +1089,11 @@ double G1Policy::predict_base_time_ms(size_t pending_cards, double G1Policy::predict_base_time_ms(size_t pending_cards) const { bool for_young_only_phase = collector_state()->in_young_only_phase(); size_t card_rs_length = _analytics->predict_card_rs_length(for_young_only_phase); + return predict_base_time_ms(pending_cards, card_rs_length); +} + +double G1Policy::predict_base_time_ms(size_t pending_cards, size_t card_rs_length) const { + bool for_young_only_phase = collector_state()->in_young_only_phase(); size_t code_root_rs_length = _analytics->predict_code_root_rs_length(for_young_only_phase); return predict_base_time_ms(pending_cards, card_rs_length, code_root_rs_length); } diff --git a/src/hotspot/share/gc/g1/g1Policy.hpp b/src/hotspot/share/gc/g1/g1Policy.hpp index 9de27e76d96..98d44408467 100644 --- a/src/hotspot/share/gc/g1/g1Policy.hpp +++ b/src/hotspot/share/gc/g1/g1Policy.hpp @@ -138,6 +138,8 @@ public: double predict_base_time_ms(size_t pending_cards) const; + double predict_base_time_ms(size_t pending_cards, size_t card_rs_length) const; + private: // Base time contains handling remembered sets and constant other time of the // whole young gen, refinement buffers, and copying survivors. diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index 0f9b9d17df7..f5f65cf1c48 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -1379,6 +1379,10 @@ public: G1ClearBitmapClosure clear(g1h); G1CombinedClosure combined(&merge, &clear); + if (_initial_evacuation) { + G1HeapRegionRemSet::iterate_for_merge(g1h->young_regions_cardset(), merge); + } + g1h->collection_set_iterate_increment_from(&combined, nullptr, worker_id); G1MergeCardSetStats stats = merge.stats(); diff --git a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp index 14fb8c0b8d2..5ea3500a7b0 100644 --- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp @@ -218,15 +218,24 @@ public: bool do_heap_region(G1HeapRegion* r) { G1HeapRegionRemSet* hrrs = r->rem_set(); + size_t occupied_cards = hrrs->occupied(); // G1HeapRegionRemSet::mem_size() includes the // size of the code roots size_t rs_unused_mem_sz = hrrs->unused_mem_size(); size_t rs_mem_sz = hrrs->mem_size(); + + if (r->is_young()) { + uint num_young = G1CollectedHeap::heap()->young_regions_count(); + occupied_cards /= num_young; + rs_unused_mem_sz /= num_young; + rs_mem_sz /= num_young; + } + if (rs_mem_sz > _max_rs_mem_sz) { _max_rs_mem_sz = rs_mem_sz; _max_rs_mem_sz_region = r; } - size_t occupied_cards = hrrs->occupied(); + size_t code_root_mem_sz = hrrs->code_roots_mem_size(); if (code_root_mem_sz > max_code_root_mem_sz()) { _max_code_root_mem_sz = code_root_mem_sz; diff --git a/src/hotspot/share/gc/g1/g1YoungCollector.cpp b/src/hotspot/share/gc/g1/g1YoungCollector.cpp index cadab2fbc48..f2fe93015c5 100644 --- a/src/hotspot/share/gc/g1/g1YoungCollector.cpp +++ b/src/hotspot/share/gc/g1/g1YoungCollector.cpp @@ -295,10 +295,9 @@ class G1PrepareEvacuationTask : public WorkerTask { G1MonotonicArenaMemoryStats _card_set_stats; void sample_card_set_size(G1HeapRegion* hr) { - // Sample card set sizes for young gen and humongous before GC: this makes - // the policy to give back memory to the OS keep the most recent amount of - // memory for these regions. - if (hr->is_young() || hr->is_starts_humongous()) { + // Sample card set sizes for humongous before GC: this makes the policy to give + // back memory to the OS keep the most recent amount of memory for these regions. + if (hr->is_starts_humongous()) { _card_set_stats.add(hr->rem_set()->card_set_memory_stats()); } } @@ -507,6 +506,9 @@ void G1YoungCollector::pre_evacuate_collection_set(G1EvacInfo* evacuation_info) { Ticks start = Ticks::now(); rem_set()->prepare_for_scan_heap_roots(); + + _g1h->prepare_group_cardsets_for_scan(); + phase_times()->record_prepare_heap_roots_time_ms((Ticks::now() - start).seconds() * 1000.0); } @@ -514,7 +516,10 @@ void G1YoungCollector::pre_evacuate_collection_set(G1EvacInfo* evacuation_info) G1PrepareEvacuationTask g1_prep_task(_g1h); Tickspan task_time = run_task_timed(&g1_prep_task); - _g1h->set_young_gen_card_set_stats(g1_prep_task.all_card_set_stats()); + G1MonotonicArenaMemoryStats sampled_card_set_stats = g1_prep_task.all_card_set_stats(); + sampled_card_set_stats.add(_g1h->young_regions_card_set_mm()->memory_stats()); + _g1h->set_young_gen_card_set_stats(sampled_card_set_stats); + _g1h->set_humongous_stats(g1_prep_task.humongous_total(), g1_prep_task.humongous_candidates()); phase_times()->record_register_regions(task_time.seconds() * 1000.0); diff --git a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp index e1f0df05c22..a0e9a9b1569 100644 --- a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp +++ b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp @@ -673,6 +673,10 @@ public: G1Policy *policy = g1h->policy(); policy->old_gen_alloc_tracker()->add_allocated_bytes_since_last_gc(_bytes_allocated_in_old_since_last_gc); + + // Add the cards from the group cardsets. + _card_rs_length += g1h->young_regions_cardset()->occupied(); + policy->record_card_rs_length(_card_rs_length); policy->cset_regions_freed(); } @@ -822,9 +826,10 @@ public: JFREventForRegion event(r, _worker_id); TimerForRegion timer(timer_for_region(r)); - stats()->account_card_rs_length(r); if (r->is_young()) { + // We only use card_rs_length statistics to estimate young regions length. + stats()->account_card_rs_length(r); assert_tracks_surviving_words(r); r->record_surv_words_in_group(_surviving_young_words[r->young_index_in_cset()]); } @@ -911,6 +916,8 @@ public: p->record_serial_free_cset_time_ms((Ticks::now() - serial_time).seconds() * 1000.0); _g1h->clear_collection_set(); + + _g1h->young_regions_cardset()->clear(); } double worker_cost() const override { return G1CollectedHeap::heap()->collection_set()->region_length(); }