152 |
152 |
153 _known_garbage_ratio(0.0), |
153 _known_garbage_ratio(0.0), |
154 _known_garbage_bytes(0), |
154 _known_garbage_bytes(0), |
155 |
155 |
156 _young_gc_eff_seq(new TruncatedSeq(TruncatedSeqLength)), |
156 _young_gc_eff_seq(new TruncatedSeq(TruncatedSeqLength)), |
157 _target_pause_time_ms(-1.0), |
|
158 |
157 |
159 _recent_prev_end_times_for_all_gcs_sec(new TruncatedSeq(NumPrevPausesForHeuristics)), |
158 _recent_prev_end_times_for_all_gcs_sec(new TruncatedSeq(NumPrevPausesForHeuristics)), |
160 |
159 |
161 _recent_CS_bytes_used_before(new TruncatedSeq(NumPrevPausesForHeuristics)), |
160 _recent_CS_bytes_used_before(new TruncatedSeq(NumPrevPausesForHeuristics)), |
162 _recent_CS_bytes_surviving(new TruncatedSeq(NumPrevPausesForHeuristics)), |
161 _recent_CS_bytes_surviving(new TruncatedSeq(NumPrevPausesForHeuristics)), |
1633 |
1632 |
1634 // Note that _mmu_tracker->max_gc_time() returns the time in seconds. |
1633 // Note that _mmu_tracker->max_gc_time() returns the time in seconds. |
1635 double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0; |
1634 double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0; |
1636 adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms); |
1635 adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms); |
1637 // </NEW PREDICTION> |
1636 // </NEW PREDICTION> |
1638 |
|
1639 _target_pause_time_ms = -1.0; |
|
1640 } |
1637 } |
1641 |
1638 |
1642 // <NEW PREDICTION> |
1639 // <NEW PREDICTION> |
1643 |
1640 |
1644 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time, |
1641 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time, |
2364 |
2361 |
2365 if (in_young_gc_mode()) { |
2362 if (in_young_gc_mode()) { |
2366 if (reached_target_length) { |
2363 if (reached_target_length) { |
2367 assert( young_list_length > 0 && _g1->young_list()->length() > 0, |
2364 assert( young_list_length > 0 && _g1->young_list()->length() > 0, |
2368 "invariant" ); |
2365 "invariant" ); |
2369 _target_pause_time_ms = max_pause_time_ms; |
|
2370 return true; |
2366 return true; |
2371 } |
2367 } |
2372 } else { |
2368 } else { |
2373 guarantee( false, "should not reach here" ); |
2369 guarantee( false, "should not reach here" ); |
2374 } |
2370 } |
2395 HRSortIndexIsOKClosure cl(_collectionSetChooser); |
2391 HRSortIndexIsOKClosure cl(_collectionSetChooser); |
2396 _g1->heap_region_iterate(&cl); |
2392 _g1->heap_region_iterate(&cl); |
2397 return true; |
2393 return true; |
2398 } |
2394 } |
2399 #endif |
2395 #endif |
|
2396 |
|
2397 bool |
|
2398 G1CollectorPolicy::force_initial_mark_if_outside_cycle() { |
|
2399 bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle(); |
|
2400 if (!during_cycle) { |
|
2401 set_initiate_conc_mark_if_possible(); |
|
2402 return true; |
|
2403 } else { |
|
2404 return false; |
|
2405 } |
|
2406 } |
2400 |
2407 |
2401 void |
2408 void |
2402 G1CollectorPolicy::decide_on_conc_mark_initiation() { |
2409 G1CollectorPolicy::decide_on_conc_mark_initiation() { |
2403 // We are about to decide on whether this pause will be an |
2410 // We are about to decide on whether this pause will be an |
2404 // initial-mark pause. |
2411 // initial-mark pause. |
2862 } |
2869 } |
2863 } |
2870 } |
2864 #endif // !PRODUCT |
2871 #endif // !PRODUCT |
2865 |
2872 |
2866 bool |
2873 bool |
2867 G1CollectorPolicy_BestRegionsFirst::choose_collection_set() { |
2874 G1CollectorPolicy_BestRegionsFirst::choose_collection_set( |
|
2875 double target_pause_time_ms) { |
2868 // Set this here - in case we're not doing young collections. |
2876 // Set this here - in case we're not doing young collections. |
2869 double non_young_start_time_sec = os::elapsedTime(); |
2877 double non_young_start_time_sec = os::elapsedTime(); |
2870 |
2878 |
2871 // The result that this routine will return. This will be set to |
2879 // The result that this routine will return. This will be set to |
2872 // false if: |
2880 // false if: |
2875 // * we add old regions to the collection set. |
2883 // * we add old regions to the collection set. |
2876 bool abandon_collection = true; |
2884 bool abandon_collection = true; |
2877 |
2885 |
2878 start_recording_regions(); |
2886 start_recording_regions(); |
2879 |
2887 |
2880 guarantee(_target_pause_time_ms > -1.0 |
2888 guarantee(target_pause_time_ms > 0.0, |
2881 NOT_PRODUCT(|| Universe::heap()->gc_cause() == GCCause::_scavenge_alot), |
2889 err_msg("target_pause_time_ms = %1.6lf should be positive", |
2882 "_target_pause_time_ms should have been set!"); |
2890 target_pause_time_ms)); |
2883 #ifndef PRODUCT |
2891 guarantee(_collection_set == NULL, "Precondition"); |
2884 if (_target_pause_time_ms <= -1.0) { |
|
2885 assert(ScavengeALot && Universe::heap()->gc_cause() == GCCause::_scavenge_alot, "Error"); |
|
2886 _target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; |
|
2887 } |
|
2888 #endif |
|
2889 assert(_collection_set == NULL, "Precondition"); |
|
2890 |
2892 |
2891 double base_time_ms = predict_base_elapsed_time_ms(_pending_cards); |
2893 double base_time_ms = predict_base_elapsed_time_ms(_pending_cards); |
2892 double predicted_pause_time_ms = base_time_ms; |
2894 double predicted_pause_time_ms = base_time_ms; |
2893 |
2895 |
2894 double target_time_ms = _target_pause_time_ms; |
2896 double time_remaining_ms = target_pause_time_ms - base_time_ms; |
2895 double time_remaining_ms = target_time_ms - base_time_ms; |
|
2896 |
2897 |
2897 // the 10% and 50% values are arbitrary... |
2898 // the 10% and 50% values are arbitrary... |
2898 if (time_remaining_ms < 0.10*target_time_ms) { |
2899 if (time_remaining_ms < 0.10 * target_pause_time_ms) { |
2899 time_remaining_ms = 0.50 * target_time_ms; |
2900 time_remaining_ms = 0.50 * target_pause_time_ms; |
2900 _within_target = false; |
2901 _within_target = false; |
2901 } else { |
2902 } else { |
2902 _within_target = true; |
2903 _within_target = true; |
2903 } |
2904 } |
2904 |
2905 |
3057 |
3058 |
3058 double non_young_end_time_sec = os::elapsedTime(); |
3059 double non_young_end_time_sec = os::elapsedTime(); |
3059 _recorded_non_young_cset_choice_time_ms = |
3060 _recorded_non_young_cset_choice_time_ms = |
3060 (non_young_end_time_sec - non_young_start_time_sec) * 1000.0; |
3061 (non_young_end_time_sec - non_young_start_time_sec) * 1000.0; |
3061 |
3062 |
3062 return abandon_collection; |
3063 // Here we are supposed to return whether the pause should be |
|
3064 // abandoned or not (i.e., whether the collection set is empty or |
|
3065 // not). However, this introduces a subtle issue when a pause is |
|
3066 // initiated explicitly with System.gc() and |
|
3067 // +ExplicitGCInvokesConcurrent (see Comment #2 in CR 6944166), it's |
|
3068 // supposed to start a marking cycle, and it's abandoned. So, by |
|
3069 // returning false here we are telling the caller never to consider |
|
3070 // a pause to be abandoned. We'll actually remove all the code |
|
3071 // associated with abandoned pauses as part of CR 6963209, but we are |
|
3072 // just disabling them this way for the moment to avoid increasing |
|
3073 // further the amount of changes for CR 6944166. |
|
3074 return false; |
3063 } |
3075 } |
3064 |
3076 |
3065 void G1CollectorPolicy_BestRegionsFirst::record_full_collection_end() { |
3077 void G1CollectorPolicy_BestRegionsFirst::record_full_collection_end() { |
3066 G1CollectorPolicy::record_full_collection_end(); |
3078 G1CollectorPolicy::record_full_collection_end(); |
3067 _collectionSetChooser->updateAfterFullCollection(); |
3079 _collectionSetChooser->updateAfterFullCollection(); |