32 #include "gc/g1/g1IHOPControl.hpp"
33 #include "gc/g1/g1GCPhaseTimes.hpp"
34 #include "gc/g1/g1Measurements.hpp"
35 #include "gc/g1/g1YoungGenSizer.hpp"
36 #include "gc/g1/heapRegion.inline.hpp"
37 #include "gc/g1/heapRegionRemSet.hpp"
38 #include "gc/shared/gcPolicyCounters.hpp"
39 #include "runtime/arguments.hpp"
40 #include "runtime/java.hpp"
41 #include "runtime/mutexLocker.hpp"
42 #include "utilities/debug.hpp"
43 #include "utilities/pair.hpp"
44
45 G1CollectorPolicy::G1CollectorPolicy() :
46 _predictor(G1ConfidencePercent / 100.0),
47 _measurements(new G1Measurements(&_predictor)),
48 _pause_time_target_ms((double) MaxGCPauseMillis),
49 _rs_lengths_prediction(0),
50 _max_survivor_regions(0),
51 _survivors_age_table(true),
52 _gc_overhead_perc(0.0),
53
54 _bytes_allocated_in_old_since_last_gc(0),
55 _ihop_control(NULL),
56 _initial_mark_to_mixed() {
57
58 // SurvRateGroups below must be initialized after the predictor because they
59 // indirectly use it through this object passed to their constructor.
60 _short_lived_surv_rate_group =
61 new SurvRateGroup(&_predictor, "Short Lived", G1YoungSurvRateNumRegionsSummary);
62 _survivor_surv_rate_group =
63 new SurvRateGroup(&_predictor, "Survivor", G1YoungSurvRateNumRegionsSummary);
64
65 // Set up the region size and associated fields. Given that the
66 // policy is created before the heap, we have to set this up here,
67 // so it's done as soon as possible.
68
69 // It would have been natural to pass initial_heap_byte_size() and
70 // max_heap_byte_size() to setup_heap_region_size() but those have
71 // not been set up at this point since they should be aligned with
72 // the region size. So, there is a circular dependency here. We base
73 // the region size on the heap size, but the heap size should be
74 // aligned with the region size. To get around this we use the
75 // unaligned values for the heap.
76 HeapRegion::setup_heap_region_size(InitialHeapSize, MaxHeapSize);
77 HeapRegionRemSet::setup_remset_size();
78
79 clear_ratio_check_data();
80
81 _phase_times = new G1GCPhaseTimes(ParallelGCThreads);
82
83 // Below, we might need to calculate the pause time target based on
84 // the pause interval. When we do so we are going to give G1 maximum
85 // flexibility and allow it to do pauses when it needs to. So, we'll
86 // arrange that the pause interval to be pause time target + 1 to
87 // ensure that a) the pause time target is maximized with respect to
88 // the pause interval and b) we maintain the invariant that pause
89 // time target < pause interval. If the user does not want this
90 // maximum flexibility, they will have to set the pause interval
91 // explicitly.
92
93 // First make sure that, if either parameter is set, its value is
94 // reasonable.
95 if (!FLAG_IS_DEFAULT(MaxGCPauseMillis)) {
96 if (MaxGCPauseMillis < 1) {
97 vm_exit_during_initialization("MaxGCPauseMillis should be "
98 "greater than 0");
99 }
100 }
125 if (FLAG_IS_DEFAULT(GCPauseIntervalMillis)) {
126 FLAG_SET_DEFAULT(GCPauseIntervalMillis, MaxGCPauseMillis + 1);
127 }
128
129 // Finally, make sure that the two parameters are consistent.
130 if (MaxGCPauseMillis >= GCPauseIntervalMillis) {
131 char buffer[256];
132 jio_snprintf(buffer, 256,
133 "MaxGCPauseMillis (%u) should be less than "
134 "GCPauseIntervalMillis (%u)",
135 MaxGCPauseMillis, GCPauseIntervalMillis);
136 vm_exit_during_initialization(buffer);
137 }
138
139 double max_gc_time = (double) MaxGCPauseMillis / 1000.0;
140 double time_slice = (double) GCPauseIntervalMillis / 1000.0;
141 _mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
142
143 _tenuring_threshold = MaxTenuringThreshold;
144
145 assert(GCTimeRatio > 0,
146 "we should have set it to a default value set_g1_gc_flags() "
147 "if a user set it to 0");
148 _gc_overhead_perc = 100.0 * (1.0 / (1.0 + GCTimeRatio));
149
150 uintx reserve_perc = G1ReservePercent;
151 // Put an artificial ceiling on this so that it's not set to a silly value.
152 if (reserve_perc > 50) {
153 reserve_perc = 50;
154 warning("G1ReservePercent is set to a value that is too large, "
155 "it's been updated to " UINTX_FORMAT, reserve_perc);
156 }
157 _reserve_factor = (double) reserve_perc / 100.0;
158 // This will be set when the heap is expanded
159 // for the first time during initialization.
160 _reserve_regions = 0;
161
162 _ihop_control = create_ihop_control();
163 }
164
165 G1CollectorPolicy::~G1CollectorPolicy() {
166 delete _ihop_control;
167 }
168
1063 size_t rs_length = hr->rem_set()->occupied();
1064 // Predicting the number of cards is based on which type of GC
1065 // we're predicting for.
1066 size_t card_num = _measurements->predict_card_num(rs_length, for_young_gc);
1067 size_t bytes_to_copy = predict_bytes_to_copy(hr);
1068
1069 double region_elapsed_time_ms =
1070 _measurements->predict_rs_scan_time_ms(card_num, collector_state()->gcs_are_young()) +
1071 _measurements->predict_object_copy_time_ms(bytes_to_copy ,collector_state()->during_concurrent_mark());
1072
1073 // The prediction of the "other" time for this region is based
1074 // upon the region type and NOT the GC type.
1075 if (hr->is_young()) {
1076 region_elapsed_time_ms += _measurements->predict_young_other_time_ms(1);
1077 } else {
1078 region_elapsed_time_ms += _measurements->predict_non_young_other_time_ms(1);
1079 }
1080 return region_elapsed_time_ms;
1081 }
1082
1083 void G1CollectorPolicy::clear_ratio_check_data() {
1084 _ratio_over_threshold_count = 0;
1085 _ratio_over_threshold_sum = 0.0;
1086 _pauses_since_start = 0;
1087 }
1088
1089 size_t G1CollectorPolicy::expansion_amount() {
1090 double recent_gc_overhead = _measurements->recent_avg_pause_time_ratio() * 100.0;
1091 double last_gc_overhead = _measurements->last_pause_time_ratio() * 100.0;
1092 double threshold = _gc_overhead_perc;
1093 size_t expand_bytes = 0;
1094
1095 // If the heap is at less than half its maximum size, scale the threshold down,
1096 // to a limit of 1. Thus the smaller the heap is, the more likely it is to expand,
1097 // though the scaling code will likely keep the increase small.
1098 if (_g1->capacity() <= _g1->max_capacity() / 2) {
1099 threshold *= (double)_g1->capacity() / (double)(_g1->max_capacity() / 2);
1100 threshold = MAX2(threshold, 1.0);
1101 }
1102
1103 // If the last GC time ratio is over the threshold, increment the count of
1104 // times it has been exceeded, and add this ratio to the sum of exceeded
1105 // ratios.
1106 if (last_gc_overhead > threshold) {
1107 _ratio_over_threshold_count++;
1108 _ratio_over_threshold_sum += last_gc_overhead;
1109 }
1110
1111 // Check if we've had enough GC time ratio checks that were over the
1112 // threshold to trigger an expansion. We'll also expand if we've
1113 // reached the end of the history buffer and the average of all entries
1114 // is still over the threshold. This indicates a smaller number of GCs were
1115 // long enough to make the average exceed the threshold.
1116 bool filled_history_buffer = _pauses_since_start == NumPrevPausesForHeuristics;
1117 if ((_ratio_over_threshold_count == MinOverThresholdForGrowth) ||
1118 (filled_history_buffer && (recent_gc_overhead > threshold))) {
1119 size_t min_expand_bytes = HeapRegion::GrainBytes;
1120 size_t reserved_bytes = _g1->max_capacity();
1121 size_t committed_bytes = _g1->capacity();
1122 size_t uncommitted_bytes = reserved_bytes - committed_bytes;
1123 size_t expand_bytes_via_pct =
1124 uncommitted_bytes * G1ExpandByPercentOfAvailable / 100;
1125 double scale_factor = 1.0;
1126
1127 // If the current size is less than 1/4 of the Initial heap size, expand
1128 // by half of the delta between the current and Initial sizes. IE, grow
1129 // back quickly.
1130 //
1131 // Otherwise, take the current size, or G1ExpandByPercentOfAvailable % of
1132 // the available expansion space, whichever is smaller, as the base
1133 // expansion size. Then possibly scale this size according to how much the
1134 // threshold has (on average) been exceeded by. If the delta is small
1135 // (less than the StartScaleDownAt value), scale the size down linearly, but
1136 // not by less than MinScaleDownFactor. If the delta is large (greater than
1137 // the StartScaleUpAt value), scale up, but adding no more than MaxScaleUpFactor
1138 // times the base size. The scaling will be linear in the range from
1139 // StartScaleUpAt to (StartScaleUpAt + ScaleUpRange). In other words,
1140 // ScaleUpRange sets the rate of scaling up.
1141 if (committed_bytes < InitialHeapSize / 4) {
1142 expand_bytes = (InitialHeapSize - committed_bytes) / 2;
1143 } else {
1144 double const MinScaleDownFactor = 0.2;
1145 double const MaxScaleUpFactor = 2;
1146 double const StartScaleDownAt = _gc_overhead_perc;
1147 double const StartScaleUpAt = _gc_overhead_perc * 1.5;
1148 double const ScaleUpRange = _gc_overhead_perc * 2.0;
1149
1150 double ratio_delta;
1151 if (filled_history_buffer) {
1152 ratio_delta = recent_gc_overhead - threshold;
1153 } else {
1154 ratio_delta = (_ratio_over_threshold_sum/_ratio_over_threshold_count) - threshold;
1155 }
1156
1157 expand_bytes = MIN2(expand_bytes_via_pct, committed_bytes);
1158 if (ratio_delta < StartScaleDownAt) {
1159 scale_factor = ratio_delta / StartScaleDownAt;
1160 scale_factor = MAX2(scale_factor, MinScaleDownFactor);
1161 } else if (ratio_delta > StartScaleUpAt) {
1162 scale_factor = 1 + ((ratio_delta - StartScaleUpAt) / ScaleUpRange);
1163 scale_factor = MIN2(scale_factor, MaxScaleUpFactor);
1164 }
1165 }
1166
1167 log_debug(gc, ergo, heap)("Attempt heap expansion (recent GC overhead higher than threshold after GC) "
1168 "recent GC overhead: %1.2f %% threshold: %1.2f %% uncommitted: " SIZE_FORMAT "B base expansion amount and scale: " SIZE_FORMAT "B (%1.2f%%)",
1169 recent_gc_overhead, threshold, uncommitted_bytes, expand_bytes, scale_factor * 100);
1170
1171 expand_bytes = static_cast<size_t>(expand_bytes * scale_factor);
1172
1173 // Ensure the expansion size is at least the minimum growth amount
1174 // and at most the remaining uncommitted byte size.
1175 expand_bytes = MAX2(expand_bytes, min_expand_bytes);
1176 expand_bytes = MIN2(expand_bytes, uncommitted_bytes);
1177
1178 clear_ratio_check_data();
1179 } else {
1180 // An expansion was not triggered. If we've started counting, increment
1181 // the number of checks we've made in the current window. If we've
1182 // reached the end of the window without resizing, clear the counters to
1183 // start again the next time we see a ratio above the threshold.
1184 if (_ratio_over_threshold_count > 0) {
1185 _pauses_since_start++;
1186 if (_pauses_since_start > NumPrevPausesForHeuristics) {
1187 clear_ratio_check_data();
1188 }
1189 }
1190 }
1191
1192 return expand_bytes;
1193 }
1194
1195 void G1CollectorPolicy::print_yg_surv_rate_info() const {
1196 #ifndef PRODUCT
1197 _short_lived_surv_rate_group->print_surv_rate_summary();
1198 // add this call for any other surv rate groups
1199 #endif // PRODUCT
1200 }
1201
1202 bool G1CollectorPolicy::is_young_list_full() const {
1203 uint young_list_length = _g1->young_list()->length();
1204 uint young_list_target_length = _young_list_target_length;
1205 return young_list_length >= young_list_target_length;
1206 }
1207
1208 bool G1CollectorPolicy::can_expand_young_list() const {
1209 uint young_list_length = _g1->young_list()->length();
1210 uint young_list_max_length = _young_list_max_length;
1211 return young_list_length < young_list_max_length;
1212 }
1213
|
32 #include "gc/g1/g1IHOPControl.hpp"
33 #include "gc/g1/g1GCPhaseTimes.hpp"
34 #include "gc/g1/g1Measurements.hpp"
35 #include "gc/g1/g1YoungGenSizer.hpp"
36 #include "gc/g1/heapRegion.inline.hpp"
37 #include "gc/g1/heapRegionRemSet.hpp"
38 #include "gc/shared/gcPolicyCounters.hpp"
39 #include "runtime/arguments.hpp"
40 #include "runtime/java.hpp"
41 #include "runtime/mutexLocker.hpp"
42 #include "utilities/debug.hpp"
43 #include "utilities/pair.hpp"
44
45 G1CollectorPolicy::G1CollectorPolicy() :
46 _predictor(G1ConfidencePercent / 100.0),
47 _measurements(new G1Measurements(&_predictor)),
48 _pause_time_target_ms((double) MaxGCPauseMillis),
49 _rs_lengths_prediction(0),
50 _max_survivor_regions(0),
51 _survivors_age_table(true),
52
53 _bytes_allocated_in_old_since_last_gc(0),
54 _ihop_control(NULL),
55 _initial_mark_to_mixed() {
56
57 // SurvRateGroups below must be initialized after the predictor because they
58 // indirectly use it through this object passed to their constructor.
59 _short_lived_surv_rate_group =
60 new SurvRateGroup(&_predictor, "Short Lived", G1YoungSurvRateNumRegionsSummary);
61 _survivor_surv_rate_group =
62 new SurvRateGroup(&_predictor, "Survivor", G1YoungSurvRateNumRegionsSummary);
63
64 // Set up the region size and associated fields. Given that the
65 // policy is created before the heap, we have to set this up here,
66 // so it's done as soon as possible.
67
68 // It would have been natural to pass initial_heap_byte_size() and
69 // max_heap_byte_size() to setup_heap_region_size() but those have
70 // not been set up at this point since they should be aligned with
71 // the region size. So, there is a circular dependency here. We base
72 // the region size on the heap size, but the heap size should be
73 // aligned with the region size. To get around this we use the
74 // unaligned values for the heap.
75 HeapRegion::setup_heap_region_size(InitialHeapSize, MaxHeapSize);
76 HeapRegionRemSet::setup_remset_size();
77
78 _phase_times = new G1GCPhaseTimes(ParallelGCThreads);
79
80 // Below, we might need to calculate the pause time target based on
81 // the pause interval. When we do so we are going to give G1 maximum
82 // flexibility and allow it to do pauses when it needs to. So, we'll
83 // arrange that the pause interval to be pause time target + 1 to
84 // ensure that a) the pause time target is maximized with respect to
85 // the pause interval and b) we maintain the invariant that pause
86 // time target < pause interval. If the user does not want this
87 // maximum flexibility, they will have to set the pause interval
88 // explicitly.
89
90 // First make sure that, if either parameter is set, its value is
91 // reasonable.
92 if (!FLAG_IS_DEFAULT(MaxGCPauseMillis)) {
93 if (MaxGCPauseMillis < 1) {
94 vm_exit_during_initialization("MaxGCPauseMillis should be "
95 "greater than 0");
96 }
97 }
122 if (FLAG_IS_DEFAULT(GCPauseIntervalMillis)) {
123 FLAG_SET_DEFAULT(GCPauseIntervalMillis, MaxGCPauseMillis + 1);
124 }
125
126 // Finally, make sure that the two parameters are consistent.
127 if (MaxGCPauseMillis >= GCPauseIntervalMillis) {
128 char buffer[256];
129 jio_snprintf(buffer, 256,
130 "MaxGCPauseMillis (%u) should be less than "
131 "GCPauseIntervalMillis (%u)",
132 MaxGCPauseMillis, GCPauseIntervalMillis);
133 vm_exit_during_initialization(buffer);
134 }
135
136 double max_gc_time = (double) MaxGCPauseMillis / 1000.0;
137 double time_slice = (double) GCPauseIntervalMillis / 1000.0;
138 _mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
139
140 _tenuring_threshold = MaxTenuringThreshold;
141
142
143 uintx reserve_perc = G1ReservePercent;
144 // Put an artificial ceiling on this so that it's not set to a silly value.
145 if (reserve_perc > 50) {
146 reserve_perc = 50;
147 warning("G1ReservePercent is set to a value that is too large, "
148 "it's been updated to " UINTX_FORMAT, reserve_perc);
149 }
150 _reserve_factor = (double) reserve_perc / 100.0;
151 // This will be set when the heap is expanded
152 // for the first time during initialization.
153 _reserve_regions = 0;
154
155 _ihop_control = create_ihop_control();
156 }
157
158 G1CollectorPolicy::~G1CollectorPolicy() {
159 delete _ihop_control;
160 }
161
1056 size_t rs_length = hr->rem_set()->occupied();
1057 // Predicting the number of cards is based on which type of GC
1058 // we're predicting for.
1059 size_t card_num = _measurements->predict_card_num(rs_length, for_young_gc);
1060 size_t bytes_to_copy = predict_bytes_to_copy(hr);
1061
1062 double region_elapsed_time_ms =
1063 _measurements->predict_rs_scan_time_ms(card_num, collector_state()->gcs_are_young()) +
1064 _measurements->predict_object_copy_time_ms(bytes_to_copy ,collector_state()->during_concurrent_mark());
1065
1066 // The prediction of the "other" time for this region is based
1067 // upon the region type and NOT the GC type.
1068 if (hr->is_young()) {
1069 region_elapsed_time_ms += _measurements->predict_young_other_time_ms(1);
1070 } else {
1071 region_elapsed_time_ms += _measurements->predict_non_young_other_time_ms(1);
1072 }
1073 return region_elapsed_time_ms;
1074 }
1075
1076
1077 void G1CollectorPolicy::print_yg_surv_rate_info() const {
1078 #ifndef PRODUCT
1079 _short_lived_surv_rate_group->print_surv_rate_summary();
1080 // add this call for any other surv rate groups
1081 #endif // PRODUCT
1082 }
1083
1084 bool G1CollectorPolicy::is_young_list_full() const {
1085 uint young_list_length = _g1->young_list()->length();
1086 uint young_list_target_length = _young_list_target_length;
1087 return young_list_length >= young_list_target_length;
1088 }
1089
1090 bool G1CollectorPolicy::can_expand_young_list() const {
1091 uint young_list_length = _g1->young_list()->length();
1092 uint young_list_max_length = _young_list_max_length;
1093 return young_list_length < young_list_max_length;
1094 }
1095
|