Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp @ 1387:0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
Summary: Ensure a full GC that clears SoftReferences before throwing an out-of-memory
Reviewed-by: ysr, jcoomes
author | jmasa |
---|---|
date | Tue, 13 Apr 2010 13:52:10 -0700 |
parents | a61af66fc99e |
children | c18cbe5936b8 |
comparison
equal
deleted
inserted
replaced
1361:6b73e879f1c2 | 1387:0bfd3fb24150 |
---|---|
1 /* | 1 /* |
2 * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. | 2 * Copyright 2004-2010 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
42 _eden_size(init_eden_size), | 42 _eden_size(init_eden_size), |
43 _promo_size(init_promo_size), | 43 _promo_size(init_promo_size), |
44 _survivor_size(init_survivor_size), | 44 _survivor_size(init_survivor_size), |
45 _gc_pause_goal_sec(gc_pause_goal_sec), | 45 _gc_pause_goal_sec(gc_pause_goal_sec), |
46 _throughput_goal(1.0 - double(1.0 / (1.0 + (double) gc_cost_ratio))), | 46 _throughput_goal(1.0 - double(1.0 / (1.0 + (double) gc_cost_ratio))), |
47 _gc_time_limit_exceeded(false), | 47 _gc_overhead_limit_exceeded(false), |
48 _print_gc_time_limit_would_be_exceeded(false), | 48 _print_gc_overhead_limit_would_be_exceeded(false), |
49 _gc_time_limit_count(0), | 49 _gc_overhead_limit_count(0), |
50 _latest_minor_mutator_interval_seconds(0), | 50 _latest_minor_mutator_interval_seconds(0), |
51 _threshold_tolerance_percent(1.0 + ThresholdTolerance/100.0), | 51 _threshold_tolerance_percent(1.0 + ThresholdTolerance/100.0), |
52 _young_gen_change_for_minor_throughput(0), | 52 _young_gen_change_for_minor_throughput(0), |
53 _old_gen_change_for_major_throughput(0) { | 53 _old_gen_change_for_major_throughput(0) { |
54 assert(AdaptiveSizePolicyGCTimeLimitThreshold > 0, | |
55 "No opportunity to clear SoftReferences before GC overhead limit"); | |
54 _avg_minor_pause = | 56 _avg_minor_pause = |
55 new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding); | 57 new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding); |
56 _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight); | 58 _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight); |
57 _avg_minor_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight); | 59 _avg_minor_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight); |
58 _avg_major_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight); | 60 _avg_major_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight); |
276 set_change_young_gen_for_throughput(0); | 278 set_change_young_gen_for_throughput(0); |
277 set_decrease_for_footprint(0); | 279 set_decrease_for_footprint(0); |
278 set_decide_at_full_gc(0); | 280 set_decide_at_full_gc(0); |
279 } | 281 } |
280 | 282 |
283 void AdaptiveSizePolicy::check_gc_overhead_limit( | |
284 size_t young_live, | |
285 size_t eden_live, | |
286 size_t max_old_gen_size, | |
287 size_t max_eden_size, | |
288 bool is_full_gc, | |
289 GCCause::Cause gc_cause, | |
290 CollectorPolicy* collector_policy) { | |
291 | |
292 // Ignore explicit GC's. Exiting here does not set the flag and | |
293 // does not reset the count. Updating of the averages for system | |
294 // GC's is still controlled by UseAdaptiveSizePolicyWithSystemGC. | |
295 if (GCCause::is_user_requested_gc(gc_cause) || | |
296 GCCause::is_serviceability_requested_gc(gc_cause)) { | |
297 return; | |
298 } | |
299 // eden_limit is the upper limit on the size of eden based on | |
300 // the maximum size of the young generation and the sizes | |
301 // of the survivor space. | |
302 // The question being asked is whether the gc costs are high | |
303 // and the space being recovered by a collection is low. | |
304 // free_in_young_gen is the free space in the young generation | |
305 // after a collection and promo_live is the free space in the old | |
306 // generation after a collection. | |
307 // | |
308 // Use the minimum of the current value of the live in the | |
309 // young gen or the average of the live in the young gen. | |
310 // If the current value drops quickly, that should be taken | |
311 // into account (i.e., don't trigger if the amount of free | |
312 // space has suddenly jumped up). If the current is much | |
313 // higher than the average, use the average since it represents | |
314 // the longer term behavor. | |
315 const size_t live_in_eden = | |
316 MIN2(eden_live, (size_t) avg_eden_live()->average()); | |
317 const size_t free_in_eden = max_eden_size > live_in_eden ? | |
318 max_eden_size - live_in_eden : 0; | |
319 const size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average()); | |
320 const size_t total_free_limit = free_in_old_gen + free_in_eden; | |
321 const size_t total_mem = max_old_gen_size + max_eden_size; | |
322 const double mem_free_limit = total_mem * (GCHeapFreeLimit/100.0); | |
323 const double mem_free_old_limit = max_old_gen_size * (GCHeapFreeLimit/100.0); | |
324 const double mem_free_eden_limit = max_eden_size * (GCHeapFreeLimit/100.0); | |
325 const double gc_cost_limit = GCTimeLimit/100.0; | |
326 size_t promo_limit = (size_t)(max_old_gen_size - avg_old_live()->average()); | |
327 // But don't force a promo size below the current promo size. Otherwise, | |
328 // the promo size will shrink for no good reason. | |
329 promo_limit = MAX2(promo_limit, _promo_size); | |
330 | |
331 | |
332 if (PrintAdaptiveSizePolicy && (Verbose || | |
333 (free_in_old_gen < (size_t) mem_free_old_limit && | |
334 free_in_eden < (size_t) mem_free_eden_limit))) { | |
335 gclog_or_tty->print_cr( | |
336 "PSAdaptiveSizePolicy::compute_generation_free_space limits:" | |
337 " promo_limit: " SIZE_FORMAT | |
338 " max_eden_size: " SIZE_FORMAT | |
339 " total_free_limit: " SIZE_FORMAT | |
340 " max_old_gen_size: " SIZE_FORMAT | |
341 " max_eden_size: " SIZE_FORMAT | |
342 " mem_free_limit: " SIZE_FORMAT, | |
343 promo_limit, max_eden_size, total_free_limit, | |
344 max_old_gen_size, max_eden_size, | |
345 (size_t) mem_free_limit); | |
346 } | |
347 | |
348 bool print_gc_overhead_limit_would_be_exceeded = false; | |
349 if (is_full_gc) { | |
350 if (gc_cost() > gc_cost_limit && | |
351 free_in_old_gen < (size_t) mem_free_old_limit && | |
352 free_in_eden < (size_t) mem_free_eden_limit) { | |
353 // Collections, on average, are taking too much time, and | |
354 // gc_cost() > gc_cost_limit | |
355 // we have too little space available after a full gc. | |
356 // total_free_limit < mem_free_limit | |
357 // where | |
358 // total_free_limit is the free space available in | |
359 // both generations | |
360 // total_mem is the total space available for allocation | |
361 // in both generations (survivor spaces are not included | |
362 // just as they are not included in eden_limit). | |
363 // mem_free_limit is a fraction of total_mem judged to be an | |
364 // acceptable amount that is still unused. | |
365 // The heap can ask for the value of this variable when deciding | |
366 // whether to thrown an OutOfMemory error. | |
367 // Note that the gc time limit test only works for the collections | |
368 // of the young gen + tenured gen and not for collections of the | |
369 // permanent gen. That is because the calculation of the space | |
370 // freed by the collection is the free space in the young gen + | |
371 // tenured gen. | |
372 // At this point the GC overhead limit is being exceeded. | |
373 inc_gc_overhead_limit_count(); | |
374 if (UseGCOverheadLimit) { | |
375 if (gc_overhead_limit_count() >= | |
376 AdaptiveSizePolicyGCTimeLimitThreshold){ | |
377 // All conditions have been met for throwing an out-of-memory | |
378 set_gc_overhead_limit_exceeded(true); | |
379 // Avoid consecutive OOM due to the gc time limit by resetting | |
380 // the counter. | |
381 reset_gc_overhead_limit_count(); | |
382 } else { | |
383 // The required consecutive collections which exceed the | |
384 // GC time limit may or may not have been reached. We | |
385 // are approaching that condition and so as not to | |
386 // throw an out-of-memory before all SoftRef's have been | |
387 // cleared, set _should_clear_all_soft_refs in CollectorPolicy. | |
388 // The clearing will be done on the next GC. | |
389 bool near_limit = gc_overhead_limit_near(); | |
390 if (near_limit) { | |
391 collector_policy->set_should_clear_all_soft_refs(true); | |
392 if (PrintGCDetails && Verbose) { | |
393 gclog_or_tty->print_cr(" Nearing GC overhead limit, " | |
394 "will be clearing all SoftReference"); | |
395 } | |
396 } | |
397 } | |
398 } | |
399 // Set this even when the overhead limit will not | |
400 // cause an out-of-memory. Diagnostic message indicating | |
401 // that the overhead limit is being exceeded is sometimes | |
402 // printed. | |
403 print_gc_overhead_limit_would_be_exceeded = true; | |
404 | |
405 } else { | |
406 // Did not exceed overhead limits | |
407 reset_gc_overhead_limit_count(); | |
408 } | |
409 } | |
410 | |
411 if (UseGCOverheadLimit && PrintGCDetails && Verbose) { | |
412 if (gc_overhead_limit_exceeded()) { | |
413 gclog_or_tty->print_cr(" GC is exceeding overhead limit " | |
414 "of %d%%", GCTimeLimit); | |
415 reset_gc_overhead_limit_count(); | |
416 } else if (print_gc_overhead_limit_would_be_exceeded) { | |
417 assert(gc_overhead_limit_count() > 0, "Should not be printing"); | |
418 gclog_or_tty->print_cr(" GC would exceed overhead limit " | |
419 "of %d%% %d consecutive time(s)", | |
420 GCTimeLimit, gc_overhead_limit_count()); | |
421 } | |
422 } | |
423 } | |
281 // Printing | 424 // Printing |
282 | 425 |
283 bool AdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) const { | 426 bool AdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) const { |
284 | 427 |
285 // Should only be used with adaptive size policy turned on. | 428 // Should only be used with adaptive size policy turned on. |