< prev index next >

src/hotspot/share/gc/g1/g1Policy.cpp

Print this page
rev 56969 : imported patch 8228609-used-vs-copied-bytes
rev 56970 : imported patch 8228609-kbarrett-review
rev 56971 : imported patch 8227739-merge-scan-rs-update-rs-cost
rev 56975 : imported patch 8227434-g1-predictions-overflow
rev 56981 : imported patch 8233588-cleanup-survrategroup
rev 56982 : [mq]: 8231579-incremental-calculation-wrong

*** 60,70 **** _full_collection_start_sec(0.0), _collection_pause_end_millis(os::javaTimeNanos() / NANOSECS_PER_MILLISEC), _young_list_target_length(0), _young_list_fixed_length(0), _young_list_max_length(0), ! _short_lived_surv_rate_group(new SurvRateGroup()), _survivor_surv_rate_group(new SurvRateGroup()), _reserve_factor((double) G1ReservePercent / 100.0), _reserve_regions(0), _young_gen_sizer(G1YoungGenSizer::create_gen_sizer()), _free_regions_at_end_of_collection(0), --- 60,70 ---- _full_collection_start_sec(0.0), _collection_pause_end_millis(os::javaTimeNanos() / NANOSECS_PER_MILLISEC), _young_list_target_length(0), _young_list_fixed_length(0), _young_list_max_length(0), ! _eden_surv_rate_group(new SurvRateGroup()), _survivor_surv_rate_group(new SurvRateGroup()), _reserve_factor((double) G1ReservePercent / 100.0), _reserve_regions(0), _young_gen_sizer(G1YoungGenSizer::create_gen_sizer()), _free_regions_at_end_of_collection(0),
*** 125,135 **** void G1Policy::note_gc_start() { phase_times()->note_gc_start(); } class G1YoungLengthPredictor { - const bool _during_cm; const double _base_time_ms; const double _base_free_regions; const double _target_pause_time_ms; const G1Policy* const _policy; --- 125,134 ----
*** 137,147 **** G1YoungLengthPredictor(bool during_cm, double base_time_ms, double base_free_regions, double target_pause_time_ms, const G1Policy* policy) : - _during_cm(during_cm), _base_time_ms(base_time_ms), _base_free_regions(base_free_regions), _target_pause_time_ms(target_pause_time_ms), _policy(policy) {} --- 136,145 ----
*** 149,163 **** if (young_length >= _base_free_regions) { // end condition 1: not enough space for the young regions return false; } ! const double accum_surv_rate = _policy->accum_yg_surv_rate_pred((int) young_length - 1); ! const size_t bytes_to_copy = ! (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes); ! const double copy_time_ms = ! _policy->analytics()->predict_object_copy_time_ms(bytes_to_copy, _during_cm); const double young_other_time_ms = _policy->analytics()->predict_young_other_time_ms(young_length); const double pause_time_ms = _base_time_ms + copy_time_ms + young_other_time_ms; if (pause_time_ms > _target_pause_time_ms) { // end condition 2: prediction is over the target pause time return false; --- 147,158 ---- if (young_length >= _base_free_regions) { // end condition 1: not enough space for the young regions return false; } ! size_t bytes_to_copy = 0; ! const double copy_time_ms = _policy->predict_eden_copy_time_ms(young_length, &bytes_to_copy); const double young_other_time_ms = _policy->analytics()->predict_young_other_time_ms(young_length); const double pause_time_ms = _base_time_ms + copy_time_ms + young_other_time_ms; if (pause_time_ms > _target_pause_time_ms) { // end condition 2: prediction is over the target pause time return false;
*** 301,312 **** result.first = young_list_target_length; return result; } ! uint ! G1Policy::calculate_young_list_target_length(size_t rs_length, uint base_min_length, uint desired_min_length, uint desired_max_length) const { assert(use_adaptive_young_list_length(), "pre-condition"); assert(collector_state()->in_young_only_phase(), "only call this for young GCs"); --- 296,306 ---- result.first = young_list_target_length; return result; } ! uint G1Policy::calculate_young_list_target_length(size_t rs_length, uint base_min_length, uint desired_min_length, uint desired_max_length) const { assert(use_adaptive_young_list_length(), "pre-condition"); assert(collector_state()->in_young_only_phase(), "only call this for young GCs");
*** 325,339 **** uint min_young_length = desired_min_length - base_min_length; assert(desired_max_length > base_min_length, "invariant"); uint max_young_length = desired_max_length - base_min_length; const double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; - const double survivor_regions_evac_time = predict_survivor_regions_evac_time(); const size_t pending_cards = _analytics->predict_pending_cards(); ! const double base_time_ms = ! predict_base_elapsed_time_ms(pending_cards, rs_length) + ! survivor_regions_evac_time; const uint available_free_regions = _free_regions_at_end_of_collection; const uint base_free_regions = available_free_regions > _reserve_regions ? available_free_regions - _reserve_regions : 0; // Here, we will make sure that the shortest young length that --- 319,330 ---- uint min_young_length = desired_min_length - base_min_length; assert(desired_max_length > base_min_length, "invariant"); uint max_young_length = desired_max_length - base_min_length; const double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; const size_t pending_cards = _analytics->predict_pending_cards(); ! const double base_time_ms = predict_base_elapsed_time_ms(pending_cards, rs_length); const uint available_free_regions = _free_regions_at_end_of_collection; const uint base_free_regions = available_free_regions > _reserve_regions ? available_free_regions - _reserve_regions : 0; // Here, we will make sure that the shortest young length that
*** 404,418 **** } double G1Policy::predict_survivor_regions_evac_time() const { double survivor_regions_evac_time = 0.0; const GrowableArray<HeapRegion*>* survivor_regions = _g1h->survivor()->regions(); - for (GrowableArrayIterator<HeapRegion*> it = survivor_regions->begin(); it != survivor_regions->end(); ++it) { ! survivor_regions_evac_time += predict_region_elapsed_time_ms(*it, collector_state()->in_young_only_phase()); } return survivor_regions_evac_time; } void G1Policy::revise_young_list_target_length_if_necessary(size_t rs_length) { --- 395,408 ---- } double G1Policy::predict_survivor_regions_evac_time() const { double survivor_regions_evac_time = 0.0; const GrowableArray<HeapRegion*>* survivor_regions = _g1h->survivor()->regions(); for (GrowableArrayIterator<HeapRegion*> it = survivor_regions->begin(); it != survivor_regions->end(); ++it) { ! survivor_regions_evac_time += predict_region_total_time_ms(*it, collector_state()->in_young_only_phase()); } return survivor_regions_evac_time; } void G1Policy::revise_young_list_target_length_if_necessary(size_t rs_length) {
*** 464,474 **** collector_state()->set_initiate_conc_mark_if_possible(need_to_start_conc_mark("end of Full GC", 0)); collector_state()->set_in_initial_mark_gc(false); collector_state()->set_mark_or_rebuild_in_progress(false); collector_state()->set_clearing_next_bitmap(false); ! _short_lived_surv_rate_group->start_adding_regions(); // also call this on any additional surv rate groups _free_regions_at_end_of_collection = _g1h->num_free_regions(); // Reset survivors SurvRateGroup. _survivor_surv_rate_group->reset(); --- 454,464 ---- collector_state()->set_initiate_conc_mark_if_possible(need_to_start_conc_mark("end of Full GC", 0)); collector_state()->set_in_initial_mark_gc(false); collector_state()->set_mark_or_rebuild_in_progress(false); collector_state()->set_clearing_next_bitmap(false); ! _eden_surv_rate_group->start_adding_regions(); // also call this on any additional surv rate groups _free_regions_at_end_of_collection = _g1h->num_free_regions(); // Reset survivors SurvRateGroup. _survivor_surv_rate_group->reset();
*** 551,561 **** record_concurrent_refinement_data(false /* is_full_collection */); _collection_set->reset_bytes_used_before(); // do that for any other surv rate groups ! _short_lived_surv_rate_group->stop_adding_regions(); _survivors_age_table.clear(); assert(_g1h->collection_set()->verify_young_ages(), "region age verification failed"); } --- 541,551 ---- record_concurrent_refinement_data(false /* is_full_collection */); _collection_set->reset_bytes_used_before(); // do that for any other surv rate groups ! _eden_surv_rate_group->stop_adding_regions(); _survivors_age_table.clear(); assert(_g1h->collection_set()->verify_young_ages(), "region age verification failed"); }
*** 709,719 **** clear_collection_set_candidates(); maybe_start_marking(); } } ! _short_lived_surv_rate_group->start_adding_regions(); double merge_hcc_time_ms = average_time_ms(G1GCPhaseTimes::MergeHCC); if (update_stats) { size_t const total_log_buffer_cards = p->sum_thread_work_items(G1GCPhaseTimes::MergeHCC, G1GCPhaseTimes::MergeHCCDirtyCards) + p->sum_thread_work_items(G1GCPhaseTimes::MergeLB, G1GCPhaseTimes::MergeLBDirtyCards); --- 699,709 ---- clear_collection_set_candidates(); maybe_start_marking(); } } ! _eden_surv_rate_group->start_adding_regions(); double merge_hcc_time_ms = average_time_ms(G1GCPhaseTimes::MergeHCC); if (update_stats) { size_t const total_log_buffer_cards = p->sum_thread_work_items(G1GCPhaseTimes::MergeHCC, G1GCPhaseTimes::MergeHCCDirtyCards) + p->sum_thread_work_items(G1GCPhaseTimes::MergeLB, G1GCPhaseTimes::MergeLBDirtyCards);
*** 905,925 **** void G1Policy::print_phases() { phase_times()->print(); } - double G1Policy::accum_yg_surv_rate_pred(int age) const { - return _short_lived_surv_rate_group->accum_surv_rate_pred(age); - } - double G1Policy::predict_base_elapsed_time_ms(size_t pending_cards, size_t rs_length) const { size_t effective_scanned_cards = _analytics->predict_scan_card_num(rs_length, collector_state()->in_young_only_phase()); return _analytics->predict_card_merge_time_ms(pending_cards + rs_length, collector_state()->in_young_only_phase()) + _analytics->predict_card_scan_time_ms(effective_scanned_cards, collector_state()->in_young_only_phase()) + ! _analytics->predict_constant_other_time_ms(); } double G1Policy::predict_base_elapsed_time_ms(size_t pending_cards) const { size_t rs_length = _analytics->predict_rs_length(); return predict_base_elapsed_time_ms(pending_cards, rs_length); --- 895,912 ---- void G1Policy::print_phases() { phase_times()->print(); } double G1Policy::predict_base_elapsed_time_ms(size_t pending_cards, size_t rs_length) const { size_t effective_scanned_cards = _analytics->predict_scan_card_num(rs_length, collector_state()->in_young_only_phase()); return _analytics->predict_card_merge_time_ms(pending_cards + rs_length, collector_state()->in_young_only_phase()) + _analytics->predict_card_scan_time_ms(effective_scanned_cards, collector_state()->in_young_only_phase()) + ! _analytics->predict_constant_other_time_ms() + ! predict_survivor_regions_evac_time(); } double G1Policy::predict_base_elapsed_time_ms(size_t pending_cards) const { size_t rs_length = _analytics->predict_rs_length(); return predict_base_elapsed_time_ms(pending_cards, rs_length);
*** 933,953 **** bytes_to_copy = (size_t) (hr->used() * hr->surv_rate_prediction(_predictor)); } return bytes_to_copy; } ! double G1Policy::predict_region_elapsed_time_ms(HeapRegion* hr, bool for_young_gc) const { size_t rs_length = hr->rem_set()->occupied(); size_t scan_card_num = _analytics->predict_scan_card_num(rs_length, for_young_gc); - size_t bytes_to_copy = predict_bytes_to_copy(hr); - double region_elapsed_time_ms = _analytics->predict_card_merge_time_ms(rs_length, collector_state()->in_young_only_phase()) + ! _analytics->predict_card_scan_time_ms(scan_card_num, collector_state()->in_young_only_phase()) + ! _analytics->predict_object_copy_time_ms(bytes_to_copy, collector_state()->mark_or_rebuild_in_progress()); // The prediction of the "other" time for this region is based // upon the region type and NOT the GC type. if (hr->is_young()) { region_elapsed_time_ms += _analytics->predict_young_other_time_ms(1); --- 920,953 ---- bytes_to_copy = (size_t) (hr->used() * hr->surv_rate_prediction(_predictor)); } return bytes_to_copy; } ! double G1Policy::predict_eden_copy_time_ms(uint count, size_t* bytes_to_copy) const { ! if (count == 0) { ! return 0.0; ! } ! size_t const expected_bytes = _eden_surv_rate_group->accum_surv_rate_pred(count) * HeapRegion::GrainBytes; ! if (bytes_to_copy != NULL) { ! *bytes_to_copy = expected_bytes; ! } ! return _analytics->predict_object_copy_time_ms(expected_bytes, collector_state()->mark_or_rebuild_in_progress()); ! } ! ! double G1Policy::predict_region_copy_time_ms(HeapRegion* hr) const { ! size_t const bytes_to_copy = predict_bytes_to_copy(hr); ! return _analytics->predict_object_copy_time_ms(bytes_to_copy, collector_state()->mark_or_rebuild_in_progress()); ! } ! ! double G1Policy::predict_region_non_copy_time_ms(HeapRegion* hr, bool for_young_gc) const { size_t rs_length = hr->rem_set()->occupied(); size_t scan_card_num = _analytics->predict_scan_card_num(rs_length, for_young_gc); double region_elapsed_time_ms = _analytics->predict_card_merge_time_ms(rs_length, collector_state()->in_young_only_phase()) + ! _analytics->predict_card_scan_time_ms(scan_card_num, collector_state()->in_young_only_phase()); // The prediction of the "other" time for this region is based // upon the region type and NOT the GC type. if (hr->is_young()) { region_elapsed_time_ms += _analytics->predict_young_other_time_ms(1);
*** 955,964 **** --- 955,968 ---- region_elapsed_time_ms += _analytics->predict_non_young_other_time_ms(1); } return region_elapsed_time_ms; } + double G1Policy::predict_region_total_time_ms(HeapRegion* hr, bool for_young_gc) const { + return predict_region_non_copy_time_ms(hr, for_young_gc) + predict_region_copy_time_ms(hr); + } + bool G1Policy::should_allocate_mutator_region() const { uint young_list_length = _g1h->young_regions_count(); uint young_list_target_length = _young_list_target_length; return young_list_length < young_list_target_length; }
*** 1302,1312 **** byte_size_in_proper_unit(reclaimable_bytes), proper_unit_for_byte_size(reclaimable_bytes), reclaimable_percent, G1HeapWastePercent); break; } ! double predicted_time_ms = predict_region_elapsed_time_ms(hr, false); time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0); // Add regions to old set until we reach the minimum amount if (num_initial_regions < min_old_cset_length) { predicted_old_time_ms += predicted_time_ms; num_initial_regions++; --- 1306,1316 ---- byte_size_in_proper_unit(reclaimable_bytes), proper_unit_for_byte_size(reclaimable_bytes), reclaimable_percent, G1HeapWastePercent); break; } ! double predicted_time_ms = predict_region_total_time_ms(hr, false); time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0); // Add regions to old set until we reach the minimum amount if (num_initial_regions < min_old_cset_length) { predicted_old_time_ms += predicted_time_ms; num_initial_regions++;
*** 1362,1372 **** uint candidate_idx = candidates->cur_idx(); HeapRegion* r = candidates->at(candidate_idx); while (num_optional_regions < max_optional_regions) { assert(r != NULL, "Region must exist"); ! prediction_ms += predict_region_elapsed_time_ms(r, false); if (prediction_ms > time_remaining_ms) { log_debug(gc, ergo, cset)("Prediction %.3fms for region %u does not fit remaining time: %.3fms.", prediction_ms, r->hrm_index(), time_remaining_ms); break; --- 1366,1376 ---- uint candidate_idx = candidates->cur_idx(); HeapRegion* r = candidates->at(candidate_idx); while (num_optional_regions < max_optional_regions) { assert(r != NULL, "Region must exist"); ! prediction_ms += predict_region_total_time_ms(r, false); if (prediction_ms > time_remaining_ms) { log_debug(gc, ergo, cset)("Prediction %.3fms for region %u does not fit remaining time: %.3fms.", prediction_ms, r->hrm_index(), time_remaining_ms); break;
< prev index next >