< prev index next >

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

Print this page

        

*** 103,113 **** _g1h = g1h; _collection_set = collection_set; assert(Heap_lock->owned_by_self(), "Locking discipline."); ! if (!use_adaptive_young_list_length()) { _young_list_fixed_length = _young_gen_sizer->min_desired_young_length(); } _young_gen_sizer->adjust_max_new_size(_g1h->max_expandable_regions()); _free_regions_at_end_of_collection = _g1h->num_free_regions(); --- 103,113 ---- _g1h = g1h; _collection_set = collection_set; assert(Heap_lock->owned_by_self(), "Locking discipline."); ! if (!adaptive_young_list_length()) { _young_list_fixed_length = _young_gen_sizer->min_desired_young_length(); } _young_gen_sizer->adjust_max_new_size(_g1h->max_expandable_regions()); _free_regions_at_end_of_collection = _g1h->num_free_regions();
*** 193,203 **** _ihop_control->update_target_occupancy(new_number_of_regions * HeapRegion::GrainBytes); } uint G1Policy::calculate_young_list_desired_min_length(uint base_min_length) const { uint desired_min_length = 0; ! if (use_adaptive_young_list_length()) { if (_analytics->num_alloc_rate_ms() > 3) { double now_sec = os::elapsedTime(); double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0; double alloc_rate_ms = _analytics->predict_alloc_rate_ms(); desired_min_length = (uint) ceil(alloc_rate_ms * when_ms); --- 193,203 ---- _ihop_control->update_target_occupancy(new_number_of_regions * HeapRegion::GrainBytes); } uint G1Policy::calculate_young_list_desired_min_length(uint base_min_length) const { uint desired_min_length = 0; ! if (adaptive_young_list_length()) { if (_analytics->num_alloc_rate_ms() > 3) { double now_sec = os::elapsedTime(); double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0; double alloc_rate_ms = _analytics->predict_alloc_rate_ms(); desired_min_length = (uint) ceil(alloc_rate_ms * when_ms);
*** 250,260 **** // Calculate the absolute and desired max bounds. uint desired_max_length = calculate_young_list_desired_max_length(); uint young_list_target_length = 0; ! if (use_adaptive_young_list_length()) { if (collector_state()->in_young_only_phase()) { young_list_target_length = calculate_young_list_target_length(rs_lengths, base_min_length, desired_min_length, --- 250,260 ---- // Calculate the absolute and desired max bounds. uint desired_max_length = calculate_young_list_desired_max_length(); uint young_list_target_length = 0; ! if (adaptive_young_list_length()) { if (collector_state()->in_young_only_phase()) { young_list_target_length = calculate_young_list_target_length(rs_lengths, base_min_length, desired_min_length,
*** 302,312 **** uint G1Policy::calculate_young_list_target_length(size_t rs_lengths, 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"); // In case some edge-condition makes the desired max length too small... if (desired_max_length <= desired_min_length) { return desired_min_length; --- 302,312 ---- uint G1Policy::calculate_young_list_target_length(size_t rs_lengths, uint base_min_length, uint desired_min_length, uint desired_max_length) const { ! assert(adaptive_young_list_length(), "pre-condition"); assert(collector_state()->in_young_only_phase(), "only call this for young GCs"); // In case some edge-condition makes the desired max length too small... if (desired_max_length <= desired_min_length) { return desired_min_length;
*** 412,422 **** } return survivor_regions_evac_time; } void G1Policy::revise_young_list_target_length_if_necessary(size_t rs_lengths) { ! guarantee(use_adaptive_young_list_length(), "should not call this otherwise" ); if (rs_lengths > _rs_lengths_prediction) { // add 10% to avoid having to recalculate often size_t rs_lengths_prediction = rs_lengths * 1100 / 1000; update_rs_lengths_prediction(rs_lengths_prediction); --- 412,422 ---- } return survivor_regions_evac_time; } void G1Policy::revise_young_list_target_length_if_necessary(size_t rs_lengths) { ! guarantee( adaptive_young_list_length(), "should not call this otherwise" ); if (rs_lengths > _rs_lengths_prediction) { // add 10% to avoid having to recalculate often size_t rs_lengths_prediction = rs_lengths * 1100 / 1000; update_rs_lengths_prediction(rs_lengths_prediction);
*** 428,438 **** void G1Policy::update_rs_lengths_prediction() { update_rs_lengths_prediction(_analytics->predict_rs_lengths()); } void G1Policy::update_rs_lengths_prediction(size_t prediction) { ! if (collector_state()->in_young_only_phase() && use_adaptive_young_list_length()) { _rs_lengths_prediction = prediction; } } void G1Policy::record_full_collection_start() { --- 428,438 ---- void G1Policy::update_rs_lengths_prediction() { update_rs_lengths_prediction(_analytics->predict_rs_lengths()); } void G1Policy::update_rs_lengths_prediction(size_t prediction) { ! if (collector_state()->in_young_only_phase() && adaptive_young_list_length()) { _rs_lengths_prediction = prediction; } } void G1Policy::record_full_collection_start() {
*** 657,671 **** } _analytics->report_cost_scan_hcc(scan_hcc_time_ms); double cost_per_entry_ms = 0.0; if (cards_scanned > 10) { ! double avg_time_scan_rs = average_time_ms(G1GCPhaseTimes::ScanRS); ! if (this_pause_was_young_only) { ! avg_time_scan_rs += average_time_ms(G1GCPhaseTimes::OptScanRS); ! } ! cost_per_entry_ms = avg_time_scan_rs / cards_scanned; _analytics->report_cost_per_entry_ms(cost_per_entry_ms, this_pause_was_young_only); } if (_max_rs_lengths > 0) { double cards_per_entry_ratio = --- 657,667 ---- } _analytics->report_cost_scan_hcc(scan_hcc_time_ms); double cost_per_entry_ms = 0.0; if (cards_scanned > 10) { ! cost_per_entry_ms = average_time_ms(G1GCPhaseTimes::ScanRS) / (double) cards_scanned; _analytics->report_cost_per_entry_ms(cost_per_entry_ms, this_pause_was_young_only); } if (_max_rs_lengths > 0) { double cards_per_entry_ratio =
*** 696,706 **** size_t freed_bytes = heap_used_bytes_before_gc - cur_used_bytes; size_t copied_bytes = _collection_set->bytes_used_before() - freed_bytes; double cost_per_byte_ms = 0.0; if (copied_bytes > 0) { ! cost_per_byte_ms = (average_time_ms(G1GCPhaseTimes::ObjCopy) + average_time_ms(G1GCPhaseTimes::OptObjCopy)) / (double) copied_bytes; _analytics->report_cost_per_byte_ms(cost_per_byte_ms, collector_state()->mark_or_rebuild_in_progress()); } if (_collection_set->young_region_length() > 0) { _analytics->report_young_other_cost_per_region_ms(young_other_time_ms() / --- 692,702 ---- size_t freed_bytes = heap_used_bytes_before_gc - cur_used_bytes; size_t copied_bytes = _collection_set->bytes_used_before() - freed_bytes; double cost_per_byte_ms = 0.0; if (copied_bytes > 0) { ! cost_per_byte_ms = average_time_ms(G1GCPhaseTimes::ObjCopy) / (double) copied_bytes; _analytics->report_cost_per_byte_ms(cost_per_byte_ms, collector_state()->mark_or_rebuild_in_progress()); } if (_collection_set->young_region_length() > 0) { _analytics->report_young_other_cost_per_region_ms(young_other_time_ms() /
*** 908,919 **** uint young_list_length = _g1h->young_regions_count(); uint young_list_max_length = _young_list_max_length; return young_list_length < young_list_max_length; } ! bool G1Policy::use_adaptive_young_list_length() const { ! return _young_gen_sizer->use_adaptive_young_list_length(); } size_t G1Policy::desired_survivor_size(uint max_regions) const { size_t const survivor_capacity = HeapRegion::GrainWords * max_regions; return (size_t)((((double)survivor_capacity) * TargetSurvivorRatio) / 100); --- 904,915 ---- uint young_list_length = _g1h->young_regions_count(); uint young_list_max_length = _young_list_max_length; return young_list_length < young_list_max_length; } ! bool G1Policy::adaptive_young_list_length() const { ! return _young_gen_sizer->adaptive_young_list_length(); } size_t G1Policy::desired_survivor_size(uint max_regions) const { size_t const survivor_capacity = HeapRegion::GrainWords * max_regions; return (size_t)((((double)survivor_capacity) * TargetSurvivorRatio) / 100);
*** 1190,1328 **** result += 1; } return (uint) result; } ! void G1Policy::calculate_old_collection_set_regions(G1CollectionSetCandidates* candidates, ! double time_remaining_ms, ! uint& num_initial_regions, ! uint& num_optional_regions) { ! assert(candidates != NULL, "Must be"); ! ! num_initial_regions = 0; ! num_optional_regions = 0; ! uint num_expensive_regions = 0; ! ! double predicted_old_time_ms = 0.0; ! double predicted_initial_time_ms = 0.0; ! double predicted_optional_time_ms = 0.0; ! ! double optional_threshold_ms = time_remaining_ms * optional_prediction_fraction(); ! ! const uint min_old_cset_length = calc_min_old_cset_length(); ! const uint max_old_cset_length = MAX2(min_old_cset_length, calc_max_old_cset_length()); ! const uint max_optional_regions = max_old_cset_length - min_old_cset_length; ! bool check_time_remaining = use_adaptive_young_list_length(); ! ! uint candidate_idx = candidates->cur_idx(); ! ! log_debug(gc, ergo, cset)("Start adding old regions to collection set. Min %u regions, max %u regions, " ! "time remaining %1.2fms, optional threshold %1.2fms", ! min_old_cset_length, max_old_cset_length, time_remaining_ms, optional_threshold_ms); ! ! HeapRegion* hr = candidates->at(candidate_idx); ! while (hr != NULL) { ! if (num_initial_regions + num_optional_regions >= max_old_cset_length) { ! // Added maximum number of old regions to the CSet. ! log_debug(gc, ergo, cset)("Finish adding old regions to collection set (Maximum number of regions). " ! "Initial %u regions, optional %u regions", ! num_initial_regions, num_optional_regions); ! break; ! } ! ! // Stop adding regions if the remaining reclaimable space is ! // not above G1HeapWastePercent. ! size_t reclaimable_bytes = candidates->remaining_reclaimable_bytes(); ! double reclaimable_percent = reclaimable_bytes_percent(reclaimable_bytes); ! double threshold = (double) G1HeapWastePercent; ! if (reclaimable_percent <= threshold) { ! // We've added enough old regions that the amount of uncollected ! // reclaimable space is at or below the waste threshold. Stop ! // adding old regions to the CSet. ! log_debug(gc, ergo, cset)("Finish adding old regions to collection set (Reclaimable percentage below threshold). " ! "Reclaimable: " SIZE_FORMAT "%s (%1.2f%%) threshold: " UINTX_FORMAT "%%", ! 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++; ! // Record the number of regions added with no time remaining ! if (time_remaining_ms == 0.0) { ! num_expensive_regions++; ! } ! } else if (!check_time_remaining) { ! // In the non-auto-tuning case, we'll finish adding regions ! // to the CSet if we reach the minimum. ! log_debug(gc, ergo, cset)("Finish adding old regions to collection set (Region amount reached min)."); ! break; ! } else { ! // Keep adding regions to old set until we reach the optional threshold ! if (time_remaining_ms > optional_threshold_ms) { ! predicted_old_time_ms += predicted_time_ms; ! num_initial_regions++; ! } else if (time_remaining_ms > 0) { ! // Keep adding optional regions until time is up. ! assert(num_optional_regions < max_optional_regions, "Should not be possible."); ! predicted_optional_time_ms += predicted_time_ms; ! num_optional_regions++; ! } else { ! log_debug(gc, ergo, cset)("Finish adding old regions to collection set (Predicted time too high)."); ! break; ! } ! } ! hr = candidates->at(++candidate_idx); ! } ! if (hr == NULL) { ! log_debug(gc, ergo, cset)("Old candidate collection set empty."); ! } ! ! if (num_expensive_regions > 0) { ! log_debug(gc, ergo, cset)("Added %u initial old regions to collection set although the predicted time was too high.", ! num_expensive_regions); ! } ! ! log_debug(gc, ergo, cset)("Finish choosing collection set old regions. Initial: %u, optional: %u, " ! "predicted old time: %1.2fms, predicted optional time: %1.2fms, time remaining: %1.2f", ! num_initial_regions, num_optional_regions, ! predicted_initial_time_ms, predicted_optional_time_ms, time_remaining_ms); ! } ! ! void G1Policy::calculate_optional_collection_set_regions(G1CollectionSetCandidates* candidates, ! uint const max_optional_regions, ! double time_remaining_ms, ! uint& num_optional_regions) { ! assert(_g1h->collector_state()->in_mixed_phase(), "Should only be called in mixed phase"); ! ! num_optional_regions = 0; ! double prediction_ms = 0; ! 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; ! } ! // This region will be included in the next optional evacuation. ! ! time_remaining_ms -= prediction_ms; ! num_optional_regions++; ! r = candidates->at(++candidate_idx); ! } ! log_debug(gc, ergo, cset)("Prepared %u regions out of %u for optional evacuation. Predicted time: %.3fms", ! num_optional_regions, max_optional_regions, prediction_ms); } void G1Policy::transfer_survivors_to_cset(const G1SurvivorRegions* survivors) { // Add survivor regions to SurvRateGroup. --- 1186,1200 ---- result += 1; } return (uint) result; } ! uint G1Policy::finalize_collection_set(double target_pause_time_ms, G1SurvivorRegions* survivor) { ! double time_remaining_ms = _collection_set->finalize_young_part(target_pause_time_ms, survivor); ! _collection_set->finalize_old_part(time_remaining_ms); ! return _collection_set->region_length(); } void G1Policy::transfer_survivors_to_cset(const G1SurvivorRegions* survivors) { // Add survivor regions to SurvRateGroup.
< prev index next >