Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @ 1656:4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
Summary: G1 was not handling explicit GCs correctly in many ways. It does now. See the CR for the list of improvements contained in this changeset.
Reviewed-by: iveresov, ysr, johnc
author | tonyp |
---|---|
date | Mon, 28 Jun 2010 14:13:17 -0400 |
parents | 215576b54709 |
children | 2d160770d2e5 |
comparison
equal
deleted
inserted
replaced
1655:e7ec8cd4dd8a | 1656:4e5661ba9d98 |
---|---|
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(); |