64 _last_allocation_time_s * 1000.0,
65 _last_allocation_time_s > 0.0 ? _last_allocated_bytes / _last_allocation_time_s : 0.0,
66 last_marking_length_s() * 1000.0);
67 }
68
69 void G1IHOPControl::send_trace_event(G1NewTracer* tracer) {
70 assert(_target_occupancy > 0, "Target occupancy still not updated yet.");
71 tracer->report_basic_ihop_statistics(get_conc_mark_start_threshold(),
72 _target_occupancy,
73 G1CollectedHeap::heap()->used(),
74 _last_allocated_bytes,
75 _last_allocation_time_s,
76 last_marking_length_s());
77 }
78
79 G1StaticIHOPControl::G1StaticIHOPControl(double ihop_percent) :
80 G1IHOPControl(ihop_percent),
81 _last_marking_length_s(0.0) {
82 }
83
84 #ifndef PRODUCT
85 static void test_update(G1IHOPControl* ctrl, double alloc_time, size_t alloc_amount, size_t young_size, double mark_time) {
86 for (int i = 0; i < 100; i++) {
87 ctrl->update_allocation_info(alloc_time, alloc_amount, young_size);
88 ctrl->update_marking_length(mark_time);
89 }
90 }
91
92 void G1StaticIHOPControl::test() {
93 size_t const initial_ihop = 45;
94
95 G1StaticIHOPControl ctrl(initial_ihop);
96 ctrl.update_target_occupancy(100);
97
98 size_t threshold = ctrl.get_conc_mark_start_threshold();
99 assert(threshold == initial_ihop,
100 "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold);
101
102 ctrl.update_allocation_info(100.0, 100, 100);
103 threshold = ctrl.get_conc_mark_start_threshold();
104 assert(threshold == initial_ihop,
105 "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold);
106
107 ctrl.update_marking_length(1000.0);
108 threshold = ctrl.get_conc_mark_start_threshold();
109 assert(threshold == initial_ihop,
110 "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold);
111
112 // Whatever we pass, the IHOP value must stay the same.
113 test_update(&ctrl, 2, 10, 10, 3);
114 threshold = ctrl.get_conc_mark_start_threshold();
115 assert(threshold == initial_ihop,
116 "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold);
117
118 test_update(&ctrl, 12, 10, 10, 3);
119 threshold = ctrl.get_conc_mark_start_threshold();
120 assert(threshold == initial_ihop,
121 "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold);
122 }
123 #endif
124
125 G1AdaptiveIHOPControl::G1AdaptiveIHOPControl(double ihop_percent,
126 G1Predictions const* predictor,
127 size_t heap_reserve_percent,
128 size_t heap_waste_percent) :
129 G1IHOPControl(ihop_percent),
130 _predictor(predictor),
131 _marking_times_s(10, 0.95),
132 _allocation_rate_s(10, 0.95),
133 _last_unrestrained_young_size(0),
134 _heap_reserve_percent(heap_reserve_percent),
135 _heap_waste_percent(heap_waste_percent)
136 {
137 }
138
139 size_t G1AdaptiveIHOPControl::actual_target_threshold() const {
140 guarantee(_target_occupancy > 0, "Target occupancy still not updated yet.");
141 // The actual target threshold takes the heap reserve and the expected waste in
142 // free space into account.
143 // _heap_reserve is that part of the total heap capacity that is reserved for
144 // eventual promotion failure.
207 get_conc_mark_start_threshold(),
208 percent_of(get_conc_mark_start_threshold(), actual_target),
209 actual_target,
210 G1CollectedHeap::heap()->used(),
211 _last_unrestrained_young_size,
212 _predictor->get_new_prediction(&_allocation_rate_s),
213 _predictor->get_new_prediction(&_marking_times_s) * 1000.0,
214 have_enough_data_for_prediction() ? "true" : "false");
215 }
216
217 void G1AdaptiveIHOPControl::send_trace_event(G1NewTracer* tracer) {
218 G1IHOPControl::send_trace_event(tracer);
219 tracer->report_adaptive_ihop_statistics(get_conc_mark_start_threshold(),
220 actual_target_threshold(),
221 G1CollectedHeap::heap()->used(),
222 _last_unrestrained_young_size,
223 _predictor->get_new_prediction(&_allocation_rate_s),
224 _predictor->get_new_prediction(&_marking_times_s),
225 have_enough_data_for_prediction());
226 }
227
228 #ifndef PRODUCT
229 void G1AdaptiveIHOPControl::test() {
230 size_t const initial_threshold = 45;
231 size_t const young_size = 10;
232 size_t const target_size = 100;
233
234 // The final IHOP value is always
235 // target_size - (young_size + alloc_amount/alloc_time * marking_time)
236
237 G1Predictions pred(0.95);
238 G1AdaptiveIHOPControl ctrl(initial_threshold, &pred, 0, 0);
239 ctrl.update_target_occupancy(target_size);
240
241 // First "load".
242 size_t const alloc_time1 = 2;
243 size_t const alloc_amount1 = 10;
244 size_t const marking_time1 = 2;
245 size_t const settled_ihop1 = target_size - (young_size + alloc_amount1/alloc_time1 * marking_time1);
246
247 size_t threshold;
248 threshold = ctrl.get_conc_mark_start_threshold();
249 assert(threshold == initial_threshold,
250 "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_threshold, threshold);
251 for (size_t i = 0; i < G1AdaptiveIHOPNumInitialSamples - 1; i++) {
252 ctrl.update_allocation_info(alloc_time1, alloc_amount1, young_size);
253 ctrl.update_marking_length(marking_time1);
254 // Not enough data yet.
255 threshold = ctrl.get_conc_mark_start_threshold();
256 assert(threshold == initial_threshold,
257 "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_threshold, threshold);
258 }
259
260 test_update(&ctrl, alloc_time1, alloc_amount1, young_size, marking_time1);
261
262 threshold = ctrl.get_conc_mark_start_threshold();
263 assert(threshold == settled_ihop1,
264 "Expected IHOP threshold to settle at " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop1, threshold);
265
266 // Second "load". A bit higher allocation rate.
267 size_t const alloc_time2 = 2;
268 size_t const alloc_amount2 = 30;
269 size_t const marking_time2 = 2;
270 size_t const settled_ihop2 = target_size - (young_size + alloc_amount2/alloc_time2 * marking_time2);
271
272 test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2);
273
274 threshold = ctrl.get_conc_mark_start_threshold();
275 assert(threshold < settled_ihop1,
276 "Expected IHOP threshold to settle at a value lower than " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop1, threshold);
277
278 // Third "load". Very high (impossible) allocation rate.
279 size_t const alloc_time3 = 1;
280 size_t const alloc_amount3 = 50;
281 size_t const marking_time3 = 2;
282 size_t const settled_ihop3 = 0;
283
284 test_update(&ctrl, alloc_time3, alloc_amount3, young_size, marking_time3);
285 threshold = ctrl.get_conc_mark_start_threshold();
286
287 assert(threshold == settled_ihop3,
288 "Expected IHOP threshold to settle at " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop3, threshold);
289
290 // And back to some arbitrary value.
291 test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2);
292
293 threshold = ctrl.get_conc_mark_start_threshold();
294 assert(threshold > settled_ihop3,
295 "Expected IHOP threshold to settle at value larger than " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop3, threshold);
296 }
297
298 void IHOP_test() {
299 G1StaticIHOPControl::test();
300 G1AdaptiveIHOPControl::test();
301 }
302 #endif
|
64 _last_allocation_time_s * 1000.0,
65 _last_allocation_time_s > 0.0 ? _last_allocated_bytes / _last_allocation_time_s : 0.0,
66 last_marking_length_s() * 1000.0);
67 }
68
69 void G1IHOPControl::send_trace_event(G1NewTracer* tracer) {
70 assert(_target_occupancy > 0, "Target occupancy still not updated yet.");
71 tracer->report_basic_ihop_statistics(get_conc_mark_start_threshold(),
72 _target_occupancy,
73 G1CollectedHeap::heap()->used(),
74 _last_allocated_bytes,
75 _last_allocation_time_s,
76 last_marking_length_s());
77 }
78
79 G1StaticIHOPControl::G1StaticIHOPControl(double ihop_percent) :
80 G1IHOPControl(ihop_percent),
81 _last_marking_length_s(0.0) {
82 }
83
84 G1AdaptiveIHOPControl::G1AdaptiveIHOPControl(double ihop_percent,
85 G1Predictions const* predictor,
86 size_t heap_reserve_percent,
87 size_t heap_waste_percent) :
88 G1IHOPControl(ihop_percent),
89 _predictor(predictor),
90 _marking_times_s(10, 0.95),
91 _allocation_rate_s(10, 0.95),
92 _last_unrestrained_young_size(0),
93 _heap_reserve_percent(heap_reserve_percent),
94 _heap_waste_percent(heap_waste_percent)
95 {
96 }
97
98 size_t G1AdaptiveIHOPControl::actual_target_threshold() const {
99 guarantee(_target_occupancy > 0, "Target occupancy still not updated yet.");
100 // The actual target threshold takes the heap reserve and the expected waste in
101 // free space into account.
102 // _heap_reserve is that part of the total heap capacity that is reserved for
103 // eventual promotion failure.
166 get_conc_mark_start_threshold(),
167 percent_of(get_conc_mark_start_threshold(), actual_target),
168 actual_target,
169 G1CollectedHeap::heap()->used(),
170 _last_unrestrained_young_size,
171 _predictor->get_new_prediction(&_allocation_rate_s),
172 _predictor->get_new_prediction(&_marking_times_s) * 1000.0,
173 have_enough_data_for_prediction() ? "true" : "false");
174 }
175
176 void G1AdaptiveIHOPControl::send_trace_event(G1NewTracer* tracer) {
177 G1IHOPControl::send_trace_event(tracer);
178 tracer->report_adaptive_ihop_statistics(get_conc_mark_start_threshold(),
179 actual_target_threshold(),
180 G1CollectedHeap::heap()->used(),
181 _last_unrestrained_young_size,
182 _predictor->get_new_prediction(&_allocation_rate_s),
183 _predictor->get_new_prediction(&_marking_times_s),
184 have_enough_data_for_prediction());
185 }
|