1.1 --- a/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp Fri Apr 09 13:08:34 2010 -0400 1.2 +++ b/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp Tue Apr 13 13:52:10 2010 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * Copyright 2004-2010 Sun Microsystems, Inc. All Rights Reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -44,13 +44,15 @@ 1.11 _survivor_size(init_survivor_size), 1.12 _gc_pause_goal_sec(gc_pause_goal_sec), 1.13 _throughput_goal(1.0 - double(1.0 / (1.0 + (double) gc_cost_ratio))), 1.14 - _gc_time_limit_exceeded(false), 1.15 - _print_gc_time_limit_would_be_exceeded(false), 1.16 - _gc_time_limit_count(0), 1.17 + _gc_overhead_limit_exceeded(false), 1.18 + _print_gc_overhead_limit_would_be_exceeded(false), 1.19 + _gc_overhead_limit_count(0), 1.20 _latest_minor_mutator_interval_seconds(0), 1.21 _threshold_tolerance_percent(1.0 + ThresholdTolerance/100.0), 1.22 _young_gen_change_for_minor_throughput(0), 1.23 _old_gen_change_for_major_throughput(0) { 1.24 + assert(AdaptiveSizePolicyGCTimeLimitThreshold > 0, 1.25 + "No opportunity to clear SoftReferences before GC overhead limit"); 1.26 _avg_minor_pause = 1.27 new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding); 1.28 _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.29 @@ -278,6 +280,147 @@ 1.30 set_decide_at_full_gc(0); 1.31 } 1.32 1.33 +void AdaptiveSizePolicy::check_gc_overhead_limit( 1.34 + size_t young_live, 1.35 + size_t eden_live, 1.36 + size_t max_old_gen_size, 1.37 + size_t max_eden_size, 1.38 + bool is_full_gc, 1.39 + GCCause::Cause gc_cause, 1.40 + CollectorPolicy* collector_policy) { 1.41 + 1.42 + // Ignore explicit GC's. Exiting here does not set the flag and 1.43 + // does not reset the count. Updating of the averages for system 1.44 + // GC's is still controlled by UseAdaptiveSizePolicyWithSystemGC. 1.45 + if (GCCause::is_user_requested_gc(gc_cause) || 1.46 + GCCause::is_serviceability_requested_gc(gc_cause)) { 1.47 + return; 1.48 + } 1.49 + // eden_limit is the upper limit on the size of eden based on 1.50 + // the maximum size of the young generation and the sizes 1.51 + // of the survivor space. 1.52 + // The question being asked is whether the gc costs are high 1.53 + // and the space being recovered by a collection is low. 1.54 + // free_in_young_gen is the free space in the young generation 1.55 + // after a collection and promo_live is the free space in the old 1.56 + // generation after a collection. 1.57 + // 1.58 + // Use the minimum of the current value of the live in the 1.59 + // young gen or the average of the live in the young gen. 1.60 + // If the current value drops quickly, that should be taken 1.61 + // into account (i.e., don't trigger if the amount of free 1.62 + // space has suddenly jumped up). If the current is much 1.63 + // higher than the average, use the average since it represents 1.64 + // the longer term behavor. 1.65 + const size_t live_in_eden = 1.66 + MIN2(eden_live, (size_t) avg_eden_live()->average()); 1.67 + const size_t free_in_eden = max_eden_size > live_in_eden ? 1.68 + max_eden_size - live_in_eden : 0; 1.69 + const size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average()); 1.70 + const size_t total_free_limit = free_in_old_gen + free_in_eden; 1.71 + const size_t total_mem = max_old_gen_size + max_eden_size; 1.72 + const double mem_free_limit = total_mem * (GCHeapFreeLimit/100.0); 1.73 + const double mem_free_old_limit = max_old_gen_size * (GCHeapFreeLimit/100.0); 1.74 + const double mem_free_eden_limit = max_eden_size * (GCHeapFreeLimit/100.0); 1.75 + const double gc_cost_limit = GCTimeLimit/100.0; 1.76 + size_t promo_limit = (size_t)(max_old_gen_size - avg_old_live()->average()); 1.77 + // But don't force a promo size below the current promo size. Otherwise, 1.78 + // the promo size will shrink for no good reason. 1.79 + promo_limit = MAX2(promo_limit, _promo_size); 1.80 + 1.81 + 1.82 + if (PrintAdaptiveSizePolicy && (Verbose || 1.83 + (free_in_old_gen < (size_t) mem_free_old_limit && 1.84 + free_in_eden < (size_t) mem_free_eden_limit))) { 1.85 + gclog_or_tty->print_cr( 1.86 + "PSAdaptiveSizePolicy::compute_generation_free_space limits:" 1.87 + " promo_limit: " SIZE_FORMAT 1.88 + " max_eden_size: " SIZE_FORMAT 1.89 + " total_free_limit: " SIZE_FORMAT 1.90 + " max_old_gen_size: " SIZE_FORMAT 1.91 + " max_eden_size: " SIZE_FORMAT 1.92 + " mem_free_limit: " SIZE_FORMAT, 1.93 + promo_limit, max_eden_size, total_free_limit, 1.94 + max_old_gen_size, max_eden_size, 1.95 + (size_t) mem_free_limit); 1.96 + } 1.97 + 1.98 + bool print_gc_overhead_limit_would_be_exceeded = false; 1.99 + if (is_full_gc) { 1.100 + if (gc_cost() > gc_cost_limit && 1.101 + free_in_old_gen < (size_t) mem_free_old_limit && 1.102 + free_in_eden < (size_t) mem_free_eden_limit) { 1.103 + // Collections, on average, are taking too much time, and 1.104 + // gc_cost() > gc_cost_limit 1.105 + // we have too little space available after a full gc. 1.106 + // total_free_limit < mem_free_limit 1.107 + // where 1.108 + // total_free_limit is the free space available in 1.109 + // both generations 1.110 + // total_mem is the total space available for allocation 1.111 + // in both generations (survivor spaces are not included 1.112 + // just as they are not included in eden_limit). 1.113 + // mem_free_limit is a fraction of total_mem judged to be an 1.114 + // acceptable amount that is still unused. 1.115 + // The heap can ask for the value of this variable when deciding 1.116 + // whether to thrown an OutOfMemory error. 1.117 + // Note that the gc time limit test only works for the collections 1.118 + // of the young gen + tenured gen and not for collections of the 1.119 + // permanent gen. That is because the calculation of the space 1.120 + // freed by the collection is the free space in the young gen + 1.121 + // tenured gen. 1.122 + // At this point the GC overhead limit is being exceeded. 1.123 + inc_gc_overhead_limit_count(); 1.124 + if (UseGCOverheadLimit) { 1.125 + if (gc_overhead_limit_count() >= 1.126 + AdaptiveSizePolicyGCTimeLimitThreshold){ 1.127 + // All conditions have been met for throwing an out-of-memory 1.128 + set_gc_overhead_limit_exceeded(true); 1.129 + // Avoid consecutive OOM due to the gc time limit by resetting 1.130 + // the counter. 1.131 + reset_gc_overhead_limit_count(); 1.132 + } else { 1.133 + // The required consecutive collections which exceed the 1.134 + // GC time limit may or may not have been reached. We 1.135 + // are approaching that condition and so as not to 1.136 + // throw an out-of-memory before all SoftRef's have been 1.137 + // cleared, set _should_clear_all_soft_refs in CollectorPolicy. 1.138 + // The clearing will be done on the next GC. 1.139 + bool near_limit = gc_overhead_limit_near(); 1.140 + if (near_limit) { 1.141 + collector_policy->set_should_clear_all_soft_refs(true); 1.142 + if (PrintGCDetails && Verbose) { 1.143 + gclog_or_tty->print_cr(" Nearing GC overhead limit, " 1.144 + "will be clearing all SoftReference"); 1.145 + } 1.146 + } 1.147 + } 1.148 + } 1.149 + // Set this even when the overhead limit will not 1.150 + // cause an out-of-memory. Diagnostic message indicating 1.151 + // that the overhead limit is being exceeded is sometimes 1.152 + // printed. 1.153 + print_gc_overhead_limit_would_be_exceeded = true; 1.154 + 1.155 + } else { 1.156 + // Did not exceed overhead limits 1.157 + reset_gc_overhead_limit_count(); 1.158 + } 1.159 + } 1.160 + 1.161 + if (UseGCOverheadLimit && PrintGCDetails && Verbose) { 1.162 + if (gc_overhead_limit_exceeded()) { 1.163 + gclog_or_tty->print_cr(" GC is exceeding overhead limit " 1.164 + "of %d%%", GCTimeLimit); 1.165 + reset_gc_overhead_limit_count(); 1.166 + } else if (print_gc_overhead_limit_would_be_exceeded) { 1.167 + assert(gc_overhead_limit_count() > 0, "Should not be printing"); 1.168 + gclog_or_tty->print_cr(" GC would exceed overhead limit " 1.169 + "of %d%% %d consecutive time(s)", 1.170 + GCTimeLimit, gc_overhead_limit_count()); 1.171 + } 1.172 + } 1.173 +} 1.174 // Printing 1.175 1.176 bool AdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) const {