--- old/src/hotspot/share/gc/g1/g1Analytics.cpp 2019-11-20 14:56:34.536946729 +0100 +++ new/src/hotspot/share/gc/g1/g1Analytics.cpp 2019-11-20 14:56:34.202936391 +0100 @@ -244,7 +244,7 @@ } size_t G1Analytics::predict_scan_card_num(size_t rs_length, bool for_young_gc) const { - if (for_young_gc || _mixed_card_merge_to_scan_ratio_seq->num() < 3) { + if (for_young_gc || !enough_samples_available(_mixed_card_merge_to_scan_ratio_seq)) { return (size_t) (rs_length * predict_young_card_merge_to_scan_ratio()); } else { return (size_t) (rs_length * get_new_prediction(_mixed_card_merge_to_scan_ratio_seq)); @@ -252,7 +252,7 @@ } double G1Analytics::predict_card_merge_time_ms(size_t card_num, bool for_young_gc) const { - if (for_young_gc || _mixed_cost_per_card_merge_ms_seq->num() < 3) { + if (for_young_gc || !enough_samples_available(_mixed_cost_per_card_merge_ms_seq->num())) { return card_num * get_new_prediction(_young_cost_per_card_merge_ms_seq); } else { return card_num * get_new_prediction(_mixed_cost_per_card_merge_ms_seq); @@ -260,7 +260,7 @@ } double G1Analytics::predict_card_scan_time_ms(size_t card_num, bool for_young_gc) const { - if (for_young_gc || _mixed_cost_per_card_scan_ms_seq->num() < 3) { + if (for_young_gc || !enough_samples_available(_mixed_cost_per_card_scan_ms_seq->num())) { return card_num * get_new_prediction(_young_cost_per_card_scan_ms_seq); } else { return card_num * get_new_prediction(_mixed_cost_per_card_scan_ms_seq); @@ -268,7 +268,7 @@ } double G1Analytics::predict_object_copy_time_ms_during_cm(size_t bytes_to_copy) const { - if (_cost_per_byte_ms_during_cm_seq->num() < 3) { + if (!enough_samples_available(_cost_per_byte_ms_during_cm_seq)) { return (1.1 * bytes_to_copy) * get_new_prediction(_copy_cost_per_byte_ms_seq); } else { return bytes_to_copy * get_new_prediction(_cost_per_byte_ms_during_cm_seq); --- old/src/hotspot/share/gc/g1/g1Analytics.hpp 2019-11-20 14:56:35.809986129 +0100 +++ new/src/hotspot/share/gc/g1/g1Analytics.hpp 2019-11-20 14:56:35.461975358 +0100 @@ -80,6 +80,10 @@ double _recent_avg_pause_time_ratio; double _last_pause_time_ratio; + // Returns whether the sequence have enough samples to get a "good" prediction. + // The constant used is random but "small". + bool enough_samples_available(TruncatedSeq const* seq) const { return seq->num() >= 3; } + double get_new_prediction(TruncatedSeq const* seq) const; size_t get_new_size_prediction(TruncatedSeq const* seq) const; --- old/src/hotspot/share/gc/g1/g1Policy.cpp 2019-11-20 14:56:37.077025344 +0100 +++ new/src/hotspot/share/gc/g1/g1Policy.cpp 2019-11-20 14:56:36.734014727 +0100 @@ -722,7 +722,11 @@ p->sum_thread_work_items(G1GCPhaseTimes::OptMergeRS, G1GCPhaseTimes::MergeRSDirtyCards) + total_log_buffer_cards; - if (total_cards_merged > 10) { + // The threshold for the number of cards in a given sampling which we consider + // large enough so that the impact from setup and other costs is negligible. + size_t const CardsNumSamplingThreshold = 10; + + if (total_cards_merged > CardsNumSamplingThreshold) { double avg_time_merge_cards = average_time_ms(G1GCPhaseTimes::MergeER) + average_time_ms(G1GCPhaseTimes::MergeRS) + average_time_ms(G1GCPhaseTimes::MergeHCC) + @@ -735,7 +739,7 @@ size_t const total_cards_scanned = p->sum_thread_work_items(G1GCPhaseTimes::ScanHR, G1GCPhaseTimes::ScanHRScannedCards) + p->sum_thread_work_items(G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::ScanHRScannedCards); - if (total_cards_scanned > 10) { + if (total_cards_scanned > CardsNumSamplingThreshold) { double avg_time_dirty_card_scan = average_time_ms(G1GCPhaseTimes::ScanHR) + average_time_ms(G1GCPhaseTimes::OptScanHR);