1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,1353 @@ 1.4 +/* 1.5 + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp" 1.30 +#include "gc_implementation/shared/gcStats.hpp" 1.31 +#include "memory/defNewGeneration.hpp" 1.32 +#include "memory/genCollectedHeap.hpp" 1.33 +#include "runtime/thread.hpp" 1.34 +#ifdef TARGET_OS_FAMILY_linux 1.35 +# include "os_linux.inline.hpp" 1.36 +#endif 1.37 +#ifdef TARGET_OS_FAMILY_solaris 1.38 +# include "os_solaris.inline.hpp" 1.39 +#endif 1.40 +#ifdef TARGET_OS_FAMILY_windows 1.41 +# include "os_windows.inline.hpp" 1.42 +#endif 1.43 +#ifdef TARGET_OS_FAMILY_aix 1.44 +# include "os_aix.inline.hpp" 1.45 +#endif 1.46 +#ifdef TARGET_OS_FAMILY_bsd 1.47 +# include "os_bsd.inline.hpp" 1.48 +#endif 1.49 +elapsedTimer CMSAdaptiveSizePolicy::_concurrent_timer; 1.50 +elapsedTimer CMSAdaptiveSizePolicy::_STW_timer; 1.51 + 1.52 +// Defined if the granularity of the time measurements is potentially too large. 1.53 +#define CLOCK_GRANULARITY_TOO_LARGE 1.54 + 1.55 +CMSAdaptiveSizePolicy::CMSAdaptiveSizePolicy(size_t init_eden_size, 1.56 + size_t init_promo_size, 1.57 + size_t init_survivor_size, 1.58 + double max_gc_minor_pause_sec, 1.59 + double max_gc_pause_sec, 1.60 + uint gc_cost_ratio) : 1.61 + AdaptiveSizePolicy(init_eden_size, 1.62 + init_promo_size, 1.63 + init_survivor_size, 1.64 + max_gc_pause_sec, 1.65 + gc_cost_ratio) { 1.66 + 1.67 + clear_internal_time_intervals(); 1.68 + 1.69 + _processor_count = os::active_processor_count(); 1.70 + 1.71 + if (CMSConcurrentMTEnabled && (ConcGCThreads > 1)) { 1.72 + assert(_processor_count > 0, "Processor count is suspect"); 1.73 + _concurrent_processor_count = MIN2((uint) ConcGCThreads, 1.74 + (uint) _processor_count); 1.75 + } else { 1.76 + _concurrent_processor_count = 1; 1.77 + } 1.78 + 1.79 + _avg_concurrent_time = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.80 + _avg_concurrent_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.81 + _avg_concurrent_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.82 + 1.83 + _avg_initial_pause = new AdaptivePaddedAverage(AdaptiveTimeWeight, 1.84 + PausePadding); 1.85 + _avg_remark_pause = new AdaptivePaddedAverage(AdaptiveTimeWeight, 1.86 + PausePadding); 1.87 + 1.88 + _avg_cms_STW_time = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.89 + _avg_cms_STW_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.90 + 1.91 + _avg_cms_free = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.92 + _avg_cms_free_at_sweep = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.93 + _avg_cms_promo = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.94 + 1.95 + // Mark-sweep-compact 1.96 + _avg_msc_pause = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.97 + _avg_msc_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.98 + _avg_msc_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.99 + 1.100 + // Mark-sweep 1.101 + _avg_ms_pause = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.102 + _avg_ms_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.103 + _avg_ms_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight); 1.104 + 1.105 + // Variables that estimate pause times as a function of generation 1.106 + // size. 1.107 + _remark_pause_old_estimator = 1.108 + new LinearLeastSquareFit(AdaptiveSizePolicyWeight); 1.109 + _initial_pause_old_estimator = 1.110 + new LinearLeastSquareFit(AdaptiveSizePolicyWeight); 1.111 + _remark_pause_young_estimator = 1.112 + new LinearLeastSquareFit(AdaptiveSizePolicyWeight); 1.113 + _initial_pause_young_estimator = 1.114 + new LinearLeastSquareFit(AdaptiveSizePolicyWeight); 1.115 + 1.116 + // Alignment comes from that used in ReservedSpace. 1.117 + _generation_alignment = os::vm_allocation_granularity(); 1.118 + 1.119 + // Start the concurrent timer here so that the first 1.120 + // concurrent_phases_begin() measures a finite mutator 1.121 + // time. A finite mutator time is used to determine 1.122 + // if a concurrent collection has been started. If this 1.123 + // proves to be a problem, use some explicit flag to 1.124 + // signal that a concurrent collection has been started. 1.125 + _concurrent_timer.start(); 1.126 + _STW_timer.start(); 1.127 +} 1.128 + 1.129 +double CMSAdaptiveSizePolicy::concurrent_processor_fraction() { 1.130 + // For now assume no other daemon threads are taking alway 1.131 + // cpu's from the application. 1.132 + return ((double) _concurrent_processor_count / (double) _processor_count); 1.133 +} 1.134 + 1.135 +double CMSAdaptiveSizePolicy::concurrent_collection_cost( 1.136 + double interval_in_seconds) { 1.137 + // When the precleaning and sweeping phases use multiple 1.138 + // threads, change one_processor_fraction to 1.139 + // concurrent_processor_fraction(). 1.140 + double one_processor_fraction = 1.0 / ((double) processor_count()); 1.141 + double concurrent_cost = 1.142 + collection_cost(_latest_cms_concurrent_marking_time_secs, 1.143 + interval_in_seconds) * concurrent_processor_fraction() + 1.144 + collection_cost(_latest_cms_concurrent_precleaning_time_secs, 1.145 + interval_in_seconds) * one_processor_fraction + 1.146 + collection_cost(_latest_cms_concurrent_sweeping_time_secs, 1.147 + interval_in_seconds) * one_processor_fraction; 1.148 + if (PrintAdaptiveSizePolicy && Verbose) { 1.149 + gclog_or_tty->print_cr( 1.150 + "\nCMSAdaptiveSizePolicy::scaled_concurrent_collection_cost(%f) " 1.151 + "_latest_cms_concurrent_marking_cost %f " 1.152 + "_latest_cms_concurrent_precleaning_cost %f " 1.153 + "_latest_cms_concurrent_sweeping_cost %f " 1.154 + "concurrent_processor_fraction %f " 1.155 + "concurrent_cost %f ", 1.156 + interval_in_seconds, 1.157 + collection_cost(_latest_cms_concurrent_marking_time_secs, 1.158 + interval_in_seconds), 1.159 + collection_cost(_latest_cms_concurrent_precleaning_time_secs, 1.160 + interval_in_seconds), 1.161 + collection_cost(_latest_cms_concurrent_sweeping_time_secs, 1.162 + interval_in_seconds), 1.163 + concurrent_processor_fraction(), 1.164 + concurrent_cost); 1.165 + } 1.166 + return concurrent_cost; 1.167 +} 1.168 + 1.169 +double CMSAdaptiveSizePolicy::concurrent_collection_time() { 1.170 + double latest_cms_sum_concurrent_phases_time_secs = 1.171 + _latest_cms_concurrent_marking_time_secs + 1.172 + _latest_cms_concurrent_precleaning_time_secs + 1.173 + _latest_cms_concurrent_sweeping_time_secs; 1.174 + return latest_cms_sum_concurrent_phases_time_secs; 1.175 +} 1.176 + 1.177 +double CMSAdaptiveSizePolicy::scaled_concurrent_collection_time() { 1.178 + // When the precleaning and sweeping phases use multiple 1.179 + // threads, change one_processor_fraction to 1.180 + // concurrent_processor_fraction(). 1.181 + double one_processor_fraction = 1.0 / ((double) processor_count()); 1.182 + double latest_cms_sum_concurrent_phases_time_secs = 1.183 + _latest_cms_concurrent_marking_time_secs * concurrent_processor_fraction() + 1.184 + _latest_cms_concurrent_precleaning_time_secs * one_processor_fraction + 1.185 + _latest_cms_concurrent_sweeping_time_secs * one_processor_fraction ; 1.186 + if (PrintAdaptiveSizePolicy && Verbose) { 1.187 + gclog_or_tty->print_cr( 1.188 + "\nCMSAdaptiveSizePolicy::scaled_concurrent_collection_time " 1.189 + "_latest_cms_concurrent_marking_time_secs %f " 1.190 + "_latest_cms_concurrent_precleaning_time_secs %f " 1.191 + "_latest_cms_concurrent_sweeping_time_secs %f " 1.192 + "concurrent_processor_fraction %f " 1.193 + "latest_cms_sum_concurrent_phases_time_secs %f ", 1.194 + _latest_cms_concurrent_marking_time_secs, 1.195 + _latest_cms_concurrent_precleaning_time_secs, 1.196 + _latest_cms_concurrent_sweeping_time_secs, 1.197 + concurrent_processor_fraction(), 1.198 + latest_cms_sum_concurrent_phases_time_secs); 1.199 + } 1.200 + return latest_cms_sum_concurrent_phases_time_secs; 1.201 +} 1.202 + 1.203 +void CMSAdaptiveSizePolicy::update_minor_pause_old_estimator( 1.204 + double minor_pause_in_ms) { 1.205 + // Get the equivalent of the free space 1.206 + // that is available for promotions in the CMS generation 1.207 + // and use that to update _minor_pause_old_estimator 1.208 + 1.209 + // Don't implement this until it is needed. A warning is 1.210 + // printed if _minor_pause_old_estimator is used. 1.211 +} 1.212 + 1.213 +void CMSAdaptiveSizePolicy::concurrent_marking_begin() { 1.214 + if (PrintAdaptiveSizePolicy && Verbose) { 1.215 + gclog_or_tty->print(" "); 1.216 + gclog_or_tty->stamp(); 1.217 + gclog_or_tty->print(": concurrent_marking_begin "); 1.218 + } 1.219 + // Update the interval time 1.220 + _concurrent_timer.stop(); 1.221 + _latest_cms_collection_end_to_collection_start_secs = _concurrent_timer.seconds(); 1.222 + if (PrintAdaptiveSizePolicy && Verbose) { 1.223 + gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::concurrent_marking_begin: " 1.224 + "mutator time %f", _latest_cms_collection_end_to_collection_start_secs); 1.225 + } 1.226 + _concurrent_timer.reset(); 1.227 + _concurrent_timer.start(); 1.228 +} 1.229 + 1.230 +void CMSAdaptiveSizePolicy::concurrent_marking_end() { 1.231 + if (PrintAdaptiveSizePolicy && Verbose) { 1.232 + gclog_or_tty->stamp(); 1.233 + gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::concurrent_marking_end()"); 1.234 + } 1.235 + 1.236 + _concurrent_timer.stop(); 1.237 + _latest_cms_concurrent_marking_time_secs = _concurrent_timer.seconds(); 1.238 + 1.239 + if (PrintAdaptiveSizePolicy && Verbose) { 1.240 + gclog_or_tty->print_cr("\n CMSAdaptiveSizePolicy::concurrent_marking_end" 1.241 + ":concurrent marking time (s) %f", 1.242 + _latest_cms_concurrent_marking_time_secs); 1.243 + } 1.244 +} 1.245 + 1.246 +void CMSAdaptiveSizePolicy::concurrent_precleaning_begin() { 1.247 + if (PrintAdaptiveSizePolicy && Verbose) { 1.248 + gclog_or_tty->stamp(); 1.249 + gclog_or_tty->print_cr( 1.250 + "CMSAdaptiveSizePolicy::concurrent_precleaning_begin()"); 1.251 + } 1.252 + _concurrent_timer.reset(); 1.253 + _concurrent_timer.start(); 1.254 +} 1.255 + 1.256 + 1.257 +void CMSAdaptiveSizePolicy::concurrent_precleaning_end() { 1.258 + if (PrintAdaptiveSizePolicy && Verbose) { 1.259 + gclog_or_tty->stamp(); 1.260 + gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::concurrent_precleaning_end()"); 1.261 + } 1.262 + 1.263 + _concurrent_timer.stop(); 1.264 + // May be set again by a second call during the same collection. 1.265 + _latest_cms_concurrent_precleaning_time_secs = _concurrent_timer.seconds(); 1.266 + 1.267 + if (PrintAdaptiveSizePolicy && Verbose) { 1.268 + gclog_or_tty->print_cr("\n CMSAdaptiveSizePolicy::concurrent_precleaning_end" 1.269 + ":concurrent precleaning time (s) %f", 1.270 + _latest_cms_concurrent_precleaning_time_secs); 1.271 + } 1.272 +} 1.273 + 1.274 +void CMSAdaptiveSizePolicy::concurrent_sweeping_begin() { 1.275 + if (PrintAdaptiveSizePolicy && Verbose) { 1.276 + gclog_or_tty->stamp(); 1.277 + gclog_or_tty->print_cr( 1.278 + "CMSAdaptiveSizePolicy::concurrent_sweeping_begin()"); 1.279 + } 1.280 + _concurrent_timer.reset(); 1.281 + _concurrent_timer.start(); 1.282 +} 1.283 + 1.284 + 1.285 +void CMSAdaptiveSizePolicy::concurrent_sweeping_end() { 1.286 + if (PrintAdaptiveSizePolicy && Verbose) { 1.287 + gclog_or_tty->stamp(); 1.288 + gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::concurrent_sweeping_end()"); 1.289 + } 1.290 + 1.291 + _concurrent_timer.stop(); 1.292 + _latest_cms_concurrent_sweeping_time_secs = _concurrent_timer.seconds(); 1.293 + 1.294 + if (PrintAdaptiveSizePolicy && Verbose) { 1.295 + gclog_or_tty->print_cr("\n CMSAdaptiveSizePolicy::concurrent_sweeping_end" 1.296 + ":concurrent sweeping time (s) %f", 1.297 + _latest_cms_concurrent_sweeping_time_secs); 1.298 + } 1.299 +} 1.300 + 1.301 +void CMSAdaptiveSizePolicy::concurrent_phases_end(GCCause::Cause gc_cause, 1.302 + size_t cur_eden, 1.303 + size_t cur_promo) { 1.304 + if (PrintAdaptiveSizePolicy && Verbose) { 1.305 + gclog_or_tty->print(" "); 1.306 + gclog_or_tty->stamp(); 1.307 + gclog_or_tty->print(": concurrent_phases_end "); 1.308 + } 1.309 + 1.310 + // Update the concurrent timer 1.311 + _concurrent_timer.stop(); 1.312 + 1.313 + if (gc_cause != GCCause::_java_lang_system_gc || 1.314 + UseAdaptiveSizePolicyWithSystemGC) { 1.315 + 1.316 + avg_cms_free()->sample(cur_promo); 1.317 + double latest_cms_sum_concurrent_phases_time_secs = 1.318 + concurrent_collection_time(); 1.319 + 1.320 + _avg_concurrent_time->sample(latest_cms_sum_concurrent_phases_time_secs); 1.321 + 1.322 + // Cost of collection (unit-less) 1.323 + 1.324 + // Total interval for collection. May not be valid. Tests 1.325 + // below determine whether to use this. 1.326 + // 1.327 + if (PrintAdaptiveSizePolicy && Verbose) { 1.328 + gclog_or_tty->print_cr("\nCMSAdaptiveSizePolicy::concurrent_phases_end \n" 1.329 + "_latest_cms_reset_end_to_initial_mark_start_secs %f \n" 1.330 + "_latest_cms_initial_mark_start_to_end_time_secs %f \n" 1.331 + "_latest_cms_remark_start_to_end_time_secs %f \n" 1.332 + "_latest_cms_concurrent_marking_time_secs %f \n" 1.333 + "_latest_cms_concurrent_precleaning_time_secs %f \n" 1.334 + "_latest_cms_concurrent_sweeping_time_secs %f \n" 1.335 + "latest_cms_sum_concurrent_phases_time_secs %f \n" 1.336 + "_latest_cms_collection_end_to_collection_start_secs %f \n" 1.337 + "concurrent_processor_fraction %f", 1.338 + _latest_cms_reset_end_to_initial_mark_start_secs, 1.339 + _latest_cms_initial_mark_start_to_end_time_secs, 1.340 + _latest_cms_remark_start_to_end_time_secs, 1.341 + _latest_cms_concurrent_marking_time_secs, 1.342 + _latest_cms_concurrent_precleaning_time_secs, 1.343 + _latest_cms_concurrent_sweeping_time_secs, 1.344 + latest_cms_sum_concurrent_phases_time_secs, 1.345 + _latest_cms_collection_end_to_collection_start_secs, 1.346 + concurrent_processor_fraction()); 1.347 + } 1.348 + double interval_in_seconds = 1.349 + _latest_cms_initial_mark_start_to_end_time_secs + 1.350 + _latest_cms_remark_start_to_end_time_secs + 1.351 + latest_cms_sum_concurrent_phases_time_secs + 1.352 + _latest_cms_collection_end_to_collection_start_secs; 1.353 + assert(interval_in_seconds >= 0.0, 1.354 + "Bad interval between cms collections"); 1.355 + 1.356 + // Sample for performance counter 1.357 + avg_concurrent_interval()->sample(interval_in_seconds); 1.358 + 1.359 + // STW costs (initial and remark pauses) 1.360 + // Cost of collection (unit-less) 1.361 + assert(_latest_cms_initial_mark_start_to_end_time_secs >= 0.0, 1.362 + "Bad initial mark pause"); 1.363 + assert(_latest_cms_remark_start_to_end_time_secs >= 0.0, 1.364 + "Bad remark pause"); 1.365 + double STW_time_in_seconds = 1.366 + _latest_cms_initial_mark_start_to_end_time_secs + 1.367 + _latest_cms_remark_start_to_end_time_secs; 1.368 + double STW_collection_cost = 0.0; 1.369 + if (interval_in_seconds > 0.0) { 1.370 + // cost for the STW phases of the concurrent collection. 1.371 + STW_collection_cost = STW_time_in_seconds / interval_in_seconds; 1.372 + avg_cms_STW_gc_cost()->sample(STW_collection_cost); 1.373 + } 1.374 + if (PrintAdaptiveSizePolicy && Verbose) { 1.375 + gclog_or_tty->print("cmsAdaptiveSizePolicy::STW_collection_end: " 1.376 + "STW gc cost: %f average: %f", STW_collection_cost, 1.377 + avg_cms_STW_gc_cost()->average()); 1.378 + gclog_or_tty->print_cr(" STW pause: %f (ms) STW period %f (ms)", 1.379 + (double) STW_time_in_seconds * MILLIUNITS, 1.380 + (double) interval_in_seconds * MILLIUNITS); 1.381 + } 1.382 + 1.383 + double concurrent_cost = 0.0; 1.384 + if (latest_cms_sum_concurrent_phases_time_secs > 0.0) { 1.385 + concurrent_cost = concurrent_collection_cost(interval_in_seconds); 1.386 + 1.387 + avg_concurrent_gc_cost()->sample(concurrent_cost); 1.388 + // Average this ms cost into all the other types gc costs 1.389 + 1.390 + if (PrintAdaptiveSizePolicy && Verbose) { 1.391 + gclog_or_tty->print("cmsAdaptiveSizePolicy::concurrent_phases_end: " 1.392 + "concurrent gc cost: %f average: %f", 1.393 + concurrent_cost, 1.394 + _avg_concurrent_gc_cost->average()); 1.395 + gclog_or_tty->print_cr(" concurrent time: %f (ms) cms period %f (ms)" 1.396 + " processor fraction: %f", 1.397 + latest_cms_sum_concurrent_phases_time_secs * MILLIUNITS, 1.398 + interval_in_seconds * MILLIUNITS, 1.399 + concurrent_processor_fraction()); 1.400 + } 1.401 + } 1.402 + double total_collection_cost = STW_collection_cost + concurrent_cost; 1.403 + avg_major_gc_cost()->sample(total_collection_cost); 1.404 + 1.405 + // Gather information for estimating future behavior 1.406 + double initial_pause_in_ms = _latest_cms_initial_mark_start_to_end_time_secs * MILLIUNITS; 1.407 + double remark_pause_in_ms = _latest_cms_remark_start_to_end_time_secs * MILLIUNITS; 1.408 + 1.409 + double cur_promo_size_in_mbytes = ((double)cur_promo)/((double)M); 1.410 + initial_pause_old_estimator()->update(cur_promo_size_in_mbytes, 1.411 + initial_pause_in_ms); 1.412 + remark_pause_old_estimator()->update(cur_promo_size_in_mbytes, 1.413 + remark_pause_in_ms); 1.414 + major_collection_estimator()->update(cur_promo_size_in_mbytes, 1.415 + total_collection_cost); 1.416 + 1.417 + // This estimate uses the average eden size. It could also 1.418 + // have used the latest eden size. Which is better? 1.419 + double cur_eden_size_in_mbytes = ((double)cur_eden)/((double) M); 1.420 + initial_pause_young_estimator()->update(cur_eden_size_in_mbytes, 1.421 + initial_pause_in_ms); 1.422 + remark_pause_young_estimator()->update(cur_eden_size_in_mbytes, 1.423 + remark_pause_in_ms); 1.424 + } 1.425 + 1.426 + clear_internal_time_intervals(); 1.427 + 1.428 + set_first_after_collection(); 1.429 + 1.430 + // The concurrent phases keeps track of it's own mutator interval 1.431 + // with this timer. This allows the stop-the-world phase to 1.432 + // be included in the mutator time so that the stop-the-world time 1.433 + // is not double counted. Reset and start it. 1.434 + _concurrent_timer.reset(); 1.435 + _concurrent_timer.start(); 1.436 + 1.437 + // The mutator time between STW phases does not include the 1.438 + // concurrent collection time. 1.439 + _STW_timer.reset(); 1.440 + _STW_timer.start(); 1.441 +} 1.442 + 1.443 +void CMSAdaptiveSizePolicy::checkpoint_roots_initial_begin() { 1.444 + // Update the interval time 1.445 + _STW_timer.stop(); 1.446 + _latest_cms_reset_end_to_initial_mark_start_secs = _STW_timer.seconds(); 1.447 + // Reset for the initial mark 1.448 + _STW_timer.reset(); 1.449 + _STW_timer.start(); 1.450 +} 1.451 + 1.452 +void CMSAdaptiveSizePolicy::checkpoint_roots_initial_end( 1.453 + GCCause::Cause gc_cause) { 1.454 + _STW_timer.stop(); 1.455 + 1.456 + if (gc_cause != GCCause::_java_lang_system_gc || 1.457 + UseAdaptiveSizePolicyWithSystemGC) { 1.458 + _latest_cms_initial_mark_start_to_end_time_secs = _STW_timer.seconds(); 1.459 + avg_initial_pause()->sample(_latest_cms_initial_mark_start_to_end_time_secs); 1.460 + 1.461 + if (PrintAdaptiveSizePolicy && Verbose) { 1.462 + gclog_or_tty->print( 1.463 + "cmsAdaptiveSizePolicy::checkpoint_roots_initial_end: " 1.464 + "initial pause: %f ", _latest_cms_initial_mark_start_to_end_time_secs); 1.465 + } 1.466 + } 1.467 + 1.468 + _STW_timer.reset(); 1.469 + _STW_timer.start(); 1.470 +} 1.471 + 1.472 +void CMSAdaptiveSizePolicy::checkpoint_roots_final_begin() { 1.473 + _STW_timer.stop(); 1.474 + _latest_cms_initial_mark_end_to_remark_start_secs = _STW_timer.seconds(); 1.475 + // Start accumumlating time for the remark in the STW timer. 1.476 + _STW_timer.reset(); 1.477 + _STW_timer.start(); 1.478 +} 1.479 + 1.480 +void CMSAdaptiveSizePolicy::checkpoint_roots_final_end( 1.481 + GCCause::Cause gc_cause) { 1.482 + _STW_timer.stop(); 1.483 + if (gc_cause != GCCause::_java_lang_system_gc || 1.484 + UseAdaptiveSizePolicyWithSystemGC) { 1.485 + // Total initial mark pause + remark pause. 1.486 + _latest_cms_remark_start_to_end_time_secs = _STW_timer.seconds(); 1.487 + double STW_time_in_seconds = _latest_cms_initial_mark_start_to_end_time_secs + 1.488 + _latest_cms_remark_start_to_end_time_secs; 1.489 + double STW_time_in_ms = STW_time_in_seconds * MILLIUNITS; 1.490 + 1.491 + avg_remark_pause()->sample(_latest_cms_remark_start_to_end_time_secs); 1.492 + 1.493 + // Sample total for initial mark + remark 1.494 + avg_cms_STW_time()->sample(STW_time_in_seconds); 1.495 + 1.496 + if (PrintAdaptiveSizePolicy && Verbose) { 1.497 + gclog_or_tty->print("cmsAdaptiveSizePolicy::checkpoint_roots_final_end: " 1.498 + "remark pause: %f", _latest_cms_remark_start_to_end_time_secs); 1.499 + } 1.500 + 1.501 + } 1.502 + // Don't start the STW times here because the concurrent 1.503 + // sweep and reset has not happened. 1.504 + // Keep the old comment above in case I don't understand 1.505 + // what is going on but now 1.506 + // Start the STW timer because it is used by ms_collection_begin() 1.507 + // and ms_collection_end() to get the sweep time if a MS is being 1.508 + // done in the foreground. 1.509 + _STW_timer.reset(); 1.510 + _STW_timer.start(); 1.511 +} 1.512 + 1.513 +void CMSAdaptiveSizePolicy::msc_collection_begin() { 1.514 + if (PrintAdaptiveSizePolicy && Verbose) { 1.515 + gclog_or_tty->print(" "); 1.516 + gclog_or_tty->stamp(); 1.517 + gclog_or_tty->print(": msc_collection_begin "); 1.518 + } 1.519 + _STW_timer.stop(); 1.520 + _latest_cms_msc_end_to_msc_start_time_secs = _STW_timer.seconds(); 1.521 + if (PrintAdaptiveSizePolicy && Verbose) { 1.522 + gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::msc_collection_begin: " 1.523 + "mutator time %f", 1.524 + _latest_cms_msc_end_to_msc_start_time_secs); 1.525 + } 1.526 + avg_msc_interval()->sample(_latest_cms_msc_end_to_msc_start_time_secs); 1.527 + _STW_timer.reset(); 1.528 + _STW_timer.start(); 1.529 +} 1.530 + 1.531 +void CMSAdaptiveSizePolicy::msc_collection_end(GCCause::Cause gc_cause) { 1.532 + if (PrintAdaptiveSizePolicy && Verbose) { 1.533 + gclog_or_tty->print(" "); 1.534 + gclog_or_tty->stamp(); 1.535 + gclog_or_tty->print(": msc_collection_end "); 1.536 + } 1.537 + _STW_timer.stop(); 1.538 + if (gc_cause != GCCause::_java_lang_system_gc || 1.539 + UseAdaptiveSizePolicyWithSystemGC) { 1.540 + double msc_pause_in_seconds = _STW_timer.seconds(); 1.541 + if ((_latest_cms_msc_end_to_msc_start_time_secs > 0.0) && 1.542 + (msc_pause_in_seconds > 0.0)) { 1.543 + avg_msc_pause()->sample(msc_pause_in_seconds); 1.544 + double mutator_time_in_seconds = 0.0; 1.545 + if (_latest_cms_collection_end_to_collection_start_secs == 0.0) { 1.546 + // This assertion may fail because of time stamp gradularity. 1.547 + // Comment it out and investiage it at a later time. The large 1.548 + // time stamp granularity occurs on some older linux systems. 1.549 +#ifndef CLOCK_GRANULARITY_TOO_LARGE 1.550 + assert((_latest_cms_concurrent_marking_time_secs == 0.0) && 1.551 + (_latest_cms_concurrent_precleaning_time_secs == 0.0) && 1.552 + (_latest_cms_concurrent_sweeping_time_secs == 0.0), 1.553 + "There should not be any concurrent time"); 1.554 +#endif 1.555 + // A concurrent collection did not start. Mutator time 1.556 + // between collections comes from the STW MSC timer. 1.557 + mutator_time_in_seconds = _latest_cms_msc_end_to_msc_start_time_secs; 1.558 + } else { 1.559 + // The concurrent collection did start so count the mutator 1.560 + // time to the start of the concurrent collection. In this 1.561 + // case the _latest_cms_msc_end_to_msc_start_time_secs measures 1.562 + // the time between the initial mark or remark and the 1.563 + // start of the MSC. That has no real meaning. 1.564 + mutator_time_in_seconds = _latest_cms_collection_end_to_collection_start_secs; 1.565 + } 1.566 + 1.567 + double latest_cms_sum_concurrent_phases_time_secs = 1.568 + concurrent_collection_time(); 1.569 + double interval_in_seconds = 1.570 + mutator_time_in_seconds + 1.571 + _latest_cms_initial_mark_start_to_end_time_secs + 1.572 + _latest_cms_remark_start_to_end_time_secs + 1.573 + latest_cms_sum_concurrent_phases_time_secs + 1.574 + msc_pause_in_seconds; 1.575 + 1.576 + if (PrintAdaptiveSizePolicy && Verbose) { 1.577 + gclog_or_tty->print_cr(" interval_in_seconds %f \n" 1.578 + " mutator_time_in_seconds %f \n" 1.579 + " _latest_cms_initial_mark_start_to_end_time_secs %f\n" 1.580 + " _latest_cms_remark_start_to_end_time_secs %f\n" 1.581 + " latest_cms_sum_concurrent_phases_time_secs %f\n" 1.582 + " msc_pause_in_seconds %f\n", 1.583 + interval_in_seconds, 1.584 + mutator_time_in_seconds, 1.585 + _latest_cms_initial_mark_start_to_end_time_secs, 1.586 + _latest_cms_remark_start_to_end_time_secs, 1.587 + latest_cms_sum_concurrent_phases_time_secs, 1.588 + msc_pause_in_seconds); 1.589 + } 1.590 + 1.591 + // The concurrent cost is wasted cost but it should be 1.592 + // included. 1.593 + double concurrent_cost = concurrent_collection_cost(interval_in_seconds); 1.594 + 1.595 + // Initial mark and remark, also wasted. 1.596 + double STW_time_in_seconds = _latest_cms_initial_mark_start_to_end_time_secs + 1.597 + _latest_cms_remark_start_to_end_time_secs; 1.598 + double STW_collection_cost = 1.599 + collection_cost(STW_time_in_seconds, interval_in_seconds) + 1.600 + concurrent_cost; 1.601 + 1.602 + if (PrintAdaptiveSizePolicy && Verbose) { 1.603 + gclog_or_tty->print_cr(" msc_collection_end:\n" 1.604 + "_latest_cms_collection_end_to_collection_start_secs %f\n" 1.605 + "_latest_cms_msc_end_to_msc_start_time_secs %f\n" 1.606 + "_latest_cms_initial_mark_start_to_end_time_secs %f\n" 1.607 + "_latest_cms_remark_start_to_end_time_secs %f\n" 1.608 + "latest_cms_sum_concurrent_phases_time_secs %f\n", 1.609 + _latest_cms_collection_end_to_collection_start_secs, 1.610 + _latest_cms_msc_end_to_msc_start_time_secs, 1.611 + _latest_cms_initial_mark_start_to_end_time_secs, 1.612 + _latest_cms_remark_start_to_end_time_secs, 1.613 + latest_cms_sum_concurrent_phases_time_secs); 1.614 + 1.615 + gclog_or_tty->print_cr(" msc_collection_end: \n" 1.616 + "latest_cms_sum_concurrent_phases_time_secs %f\n" 1.617 + "STW_time_in_seconds %f\n" 1.618 + "msc_pause_in_seconds %f\n", 1.619 + latest_cms_sum_concurrent_phases_time_secs, 1.620 + STW_time_in_seconds, 1.621 + msc_pause_in_seconds); 1.622 + } 1.623 + 1.624 + double cost = concurrent_cost + STW_collection_cost + 1.625 + collection_cost(msc_pause_in_seconds, interval_in_seconds); 1.626 + 1.627 + _avg_msc_gc_cost->sample(cost); 1.628 + 1.629 + // Average this ms cost into all the other types gc costs 1.630 + avg_major_gc_cost()->sample(cost); 1.631 + 1.632 + // Sample for performance counter 1.633 + _avg_msc_interval->sample(interval_in_seconds); 1.634 + if (PrintAdaptiveSizePolicy && Verbose) { 1.635 + gclog_or_tty->print("cmsAdaptiveSizePolicy::msc_collection_end: " 1.636 + "MSC gc cost: %f average: %f", cost, 1.637 + _avg_msc_gc_cost->average()); 1.638 + 1.639 + double msc_pause_in_ms = msc_pause_in_seconds * MILLIUNITS; 1.640 + gclog_or_tty->print_cr(" MSC pause: %f (ms) MSC period %f (ms)", 1.641 + msc_pause_in_ms, (double) interval_in_seconds * MILLIUNITS); 1.642 + } 1.643 + } 1.644 + } 1.645 + 1.646 + clear_internal_time_intervals(); 1.647 + 1.648 + // Can this call be put into the epilogue? 1.649 + set_first_after_collection(); 1.650 + 1.651 + // The concurrent phases keeps track of it's own mutator interval 1.652 + // with this timer. This allows the stop-the-world phase to 1.653 + // be included in the mutator time so that the stop-the-world time 1.654 + // is not double counted. Reset and start it. 1.655 + _concurrent_timer.stop(); 1.656 + _concurrent_timer.reset(); 1.657 + _concurrent_timer.start(); 1.658 + 1.659 + _STW_timer.reset(); 1.660 + _STW_timer.start(); 1.661 +} 1.662 + 1.663 +void CMSAdaptiveSizePolicy::ms_collection_begin() { 1.664 + if (PrintAdaptiveSizePolicy && Verbose) { 1.665 + gclog_or_tty->print(" "); 1.666 + gclog_or_tty->stamp(); 1.667 + gclog_or_tty->print(": ms_collection_begin "); 1.668 + } 1.669 + _STW_timer.stop(); 1.670 + _latest_cms_ms_end_to_ms_start = _STW_timer.seconds(); 1.671 + if (PrintAdaptiveSizePolicy && Verbose) { 1.672 + gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::ms_collection_begin: " 1.673 + "mutator time %f", 1.674 + _latest_cms_ms_end_to_ms_start); 1.675 + } 1.676 + avg_ms_interval()->sample(_STW_timer.seconds()); 1.677 + _STW_timer.reset(); 1.678 + _STW_timer.start(); 1.679 +} 1.680 + 1.681 +void CMSAdaptiveSizePolicy::ms_collection_end(GCCause::Cause gc_cause) { 1.682 + if (PrintAdaptiveSizePolicy && Verbose) { 1.683 + gclog_or_tty->print(" "); 1.684 + gclog_or_tty->stamp(); 1.685 + gclog_or_tty->print(": ms_collection_end "); 1.686 + } 1.687 + _STW_timer.stop(); 1.688 + if (gc_cause != GCCause::_java_lang_system_gc || 1.689 + UseAdaptiveSizePolicyWithSystemGC) { 1.690 + // The MS collection is a foreground collection that does all 1.691 + // the parts of a mostly concurrent collection. 1.692 + // 1.693 + // For this collection include the cost of the 1.694 + // initial mark 1.695 + // remark 1.696 + // all concurrent time (scaled down by the 1.697 + // concurrent_processor_fraction). Some 1.698 + // may be zero if the baton was passed before 1.699 + // it was reached. 1.700 + // concurrent marking 1.701 + // sweeping 1.702 + // resetting 1.703 + // STW after baton was passed (STW_in_foreground_in_seconds) 1.704 + double STW_in_foreground_in_seconds = _STW_timer.seconds(); 1.705 + 1.706 + double latest_cms_sum_concurrent_phases_time_secs = 1.707 + concurrent_collection_time(); 1.708 + if (PrintAdaptiveSizePolicy && Verbose) { 1.709 + gclog_or_tty->print_cr("\nCMSAdaptiveSizePolicy::ms_collecton_end " 1.710 + "STW_in_foreground_in_seconds %f " 1.711 + "_latest_cms_initial_mark_start_to_end_time_secs %f " 1.712 + "_latest_cms_remark_start_to_end_time_secs %f " 1.713 + "latest_cms_sum_concurrent_phases_time_secs %f " 1.714 + "_latest_cms_ms_marking_start_to_end_time_secs %f " 1.715 + "_latest_cms_ms_end_to_ms_start %f", 1.716 + STW_in_foreground_in_seconds, 1.717 + _latest_cms_initial_mark_start_to_end_time_secs, 1.718 + _latest_cms_remark_start_to_end_time_secs, 1.719 + latest_cms_sum_concurrent_phases_time_secs, 1.720 + _latest_cms_ms_marking_start_to_end_time_secs, 1.721 + _latest_cms_ms_end_to_ms_start); 1.722 + } 1.723 + 1.724 + double STW_marking_in_seconds = _latest_cms_initial_mark_start_to_end_time_secs + 1.725 + _latest_cms_remark_start_to_end_time_secs; 1.726 +#ifndef CLOCK_GRANULARITY_TOO_LARGE 1.727 + assert(_latest_cms_ms_marking_start_to_end_time_secs == 0.0 || 1.728 + latest_cms_sum_concurrent_phases_time_secs == 0.0, 1.729 + "marking done twice?"); 1.730 +#endif 1.731 + double ms_time_in_seconds = STW_marking_in_seconds + 1.732 + STW_in_foreground_in_seconds + 1.733 + _latest_cms_ms_marking_start_to_end_time_secs + 1.734 + scaled_concurrent_collection_time(); 1.735 + avg_ms_pause()->sample(ms_time_in_seconds); 1.736 + // Use the STW costs from the initial mark and remark plus 1.737 + // the cost of the concurrent phase to calculate a 1.738 + // collection cost. 1.739 + double cost = 0.0; 1.740 + if ((_latest_cms_ms_end_to_ms_start > 0.0) && 1.741 + (ms_time_in_seconds > 0.0)) { 1.742 + double interval_in_seconds = 1.743 + _latest_cms_ms_end_to_ms_start + ms_time_in_seconds; 1.744 + 1.745 + if (PrintAdaptiveSizePolicy && Verbose) { 1.746 + gclog_or_tty->print_cr("\n ms_time_in_seconds %f " 1.747 + "latest_cms_sum_concurrent_phases_time_secs %f " 1.748 + "interval_in_seconds %f", 1.749 + ms_time_in_seconds, 1.750 + latest_cms_sum_concurrent_phases_time_secs, 1.751 + interval_in_seconds); 1.752 + } 1.753 + 1.754 + cost = collection_cost(ms_time_in_seconds, interval_in_seconds); 1.755 + 1.756 + _avg_ms_gc_cost->sample(cost); 1.757 + // Average this ms cost into all the other types gc costs 1.758 + avg_major_gc_cost()->sample(cost); 1.759 + 1.760 + // Sample for performance counter 1.761 + _avg_ms_interval->sample(interval_in_seconds); 1.762 + } 1.763 + if (PrintAdaptiveSizePolicy && Verbose) { 1.764 + gclog_or_tty->print("cmsAdaptiveSizePolicy::ms_collection_end: " 1.765 + "MS gc cost: %f average: %f", cost, _avg_ms_gc_cost->average()); 1.766 + 1.767 + double ms_time_in_ms = ms_time_in_seconds * MILLIUNITS; 1.768 + gclog_or_tty->print_cr(" MS pause: %f (ms) MS period %f (ms)", 1.769 + ms_time_in_ms, 1.770 + _latest_cms_ms_end_to_ms_start * MILLIUNITS); 1.771 + } 1.772 + } 1.773 + 1.774 + // Consider putting this code (here to end) into a 1.775 + // method for convenience. 1.776 + clear_internal_time_intervals(); 1.777 + 1.778 + set_first_after_collection(); 1.779 + 1.780 + // The concurrent phases keeps track of it's own mutator interval 1.781 + // with this timer. This allows the stop-the-world phase to 1.782 + // be included in the mutator time so that the stop-the-world time 1.783 + // is not double counted. Reset and start it. 1.784 + _concurrent_timer.stop(); 1.785 + _concurrent_timer.reset(); 1.786 + _concurrent_timer.start(); 1.787 + 1.788 + _STW_timer.reset(); 1.789 + _STW_timer.start(); 1.790 +} 1.791 + 1.792 +void CMSAdaptiveSizePolicy::clear_internal_time_intervals() { 1.793 + _latest_cms_reset_end_to_initial_mark_start_secs = 0.0; 1.794 + _latest_cms_initial_mark_end_to_remark_start_secs = 0.0; 1.795 + _latest_cms_collection_end_to_collection_start_secs = 0.0; 1.796 + _latest_cms_concurrent_marking_time_secs = 0.0; 1.797 + _latest_cms_concurrent_precleaning_time_secs = 0.0; 1.798 + _latest_cms_concurrent_sweeping_time_secs = 0.0; 1.799 + _latest_cms_msc_end_to_msc_start_time_secs = 0.0; 1.800 + _latest_cms_ms_end_to_ms_start = 0.0; 1.801 + _latest_cms_remark_start_to_end_time_secs = 0.0; 1.802 + _latest_cms_initial_mark_start_to_end_time_secs = 0.0; 1.803 + _latest_cms_ms_marking_start_to_end_time_secs = 0.0; 1.804 +} 1.805 + 1.806 +void CMSAdaptiveSizePolicy::clear_generation_free_space_flags() { 1.807 + AdaptiveSizePolicy::clear_generation_free_space_flags(); 1.808 + 1.809 + set_change_young_gen_for_maj_pauses(0); 1.810 +} 1.811 + 1.812 +void CMSAdaptiveSizePolicy::concurrent_phases_resume() { 1.813 + if (PrintAdaptiveSizePolicy && Verbose) { 1.814 + gclog_or_tty->stamp(); 1.815 + gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::concurrent_phases_resume()"); 1.816 + } 1.817 + _concurrent_timer.start(); 1.818 +} 1.819 + 1.820 +double CMSAdaptiveSizePolicy::time_since_major_gc() const { 1.821 + _concurrent_timer.stop(); 1.822 + double time_since_cms_gc = _concurrent_timer.seconds(); 1.823 + _concurrent_timer.start(); 1.824 + _STW_timer.stop(); 1.825 + double time_since_STW_gc = _STW_timer.seconds(); 1.826 + _STW_timer.start(); 1.827 + 1.828 + return MIN2(time_since_cms_gc, time_since_STW_gc); 1.829 +} 1.830 + 1.831 +double CMSAdaptiveSizePolicy::major_gc_interval_average_for_decay() const { 1.832 + double cms_interval = _avg_concurrent_interval->average(); 1.833 + double msc_interval = _avg_msc_interval->average(); 1.834 + double ms_interval = _avg_ms_interval->average(); 1.835 + 1.836 + return MAX3(cms_interval, msc_interval, ms_interval); 1.837 +} 1.838 + 1.839 +double CMSAdaptiveSizePolicy::cms_gc_cost() const { 1.840 + return avg_major_gc_cost()->average(); 1.841 +} 1.842 + 1.843 +void CMSAdaptiveSizePolicy::ms_collection_marking_begin() { 1.844 + _STW_timer.stop(); 1.845 + // Start accumumlating time for the marking in the STW timer. 1.846 + _STW_timer.reset(); 1.847 + _STW_timer.start(); 1.848 +} 1.849 + 1.850 +void CMSAdaptiveSizePolicy::ms_collection_marking_end( 1.851 + GCCause::Cause gc_cause) { 1.852 + _STW_timer.stop(); 1.853 + if (gc_cause != GCCause::_java_lang_system_gc || 1.854 + UseAdaptiveSizePolicyWithSystemGC) { 1.855 + _latest_cms_ms_marking_start_to_end_time_secs = _STW_timer.seconds(); 1.856 + if (PrintAdaptiveSizePolicy && Verbose) { 1.857 + gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::" 1.858 + "msc_collection_marking_end: mutator time %f", 1.859 + _latest_cms_ms_marking_start_to_end_time_secs); 1.860 + } 1.861 + } 1.862 + _STW_timer.reset(); 1.863 + _STW_timer.start(); 1.864 +} 1.865 + 1.866 +double CMSAdaptiveSizePolicy::gc_cost() const { 1.867 + double cms_gen_cost = cms_gc_cost(); 1.868 + double result = MIN2(1.0, minor_gc_cost() + cms_gen_cost); 1.869 + assert(result >= 0.0, "Both minor and major costs are non-negative"); 1.870 + return result; 1.871 +} 1.872 + 1.873 +// Cost of collection (unit-less) 1.874 +double CMSAdaptiveSizePolicy::collection_cost(double pause_in_seconds, 1.875 + double interval_in_seconds) { 1.876 + // Cost of collection (unit-less) 1.877 + double cost = 0.0; 1.878 + if ((interval_in_seconds > 0.0) && 1.879 + (pause_in_seconds > 0.0)) { 1.880 + cost = 1.881 + pause_in_seconds / interval_in_seconds; 1.882 + } 1.883 + return cost; 1.884 +} 1.885 + 1.886 +size_t CMSAdaptiveSizePolicy::adjust_eden_for_pause_time(size_t cur_eden) { 1.887 + size_t change = 0; 1.888 + size_t desired_eden = cur_eden; 1.889 + 1.890 + // reduce eden size 1.891 + change = eden_decrement_aligned_down(cur_eden); 1.892 + desired_eden = cur_eden - change; 1.893 + 1.894 + if (PrintAdaptiveSizePolicy && Verbose) { 1.895 + gclog_or_tty->print_cr( 1.896 + "CMSAdaptiveSizePolicy::adjust_eden_for_pause_time " 1.897 + "adjusting eden for pause time. " 1.898 + " starting eden size " SIZE_FORMAT 1.899 + " reduced eden size " SIZE_FORMAT 1.900 + " eden delta " SIZE_FORMAT, 1.901 + cur_eden, desired_eden, change); 1.902 + } 1.903 + 1.904 + return desired_eden; 1.905 +} 1.906 + 1.907 +size_t CMSAdaptiveSizePolicy::adjust_eden_for_throughput(size_t cur_eden) { 1.908 + 1.909 + size_t desired_eden = cur_eden; 1.910 + 1.911 + set_change_young_gen_for_throughput(increase_young_gen_for_througput_true); 1.912 + 1.913 + size_t change = eden_increment_aligned_up(cur_eden); 1.914 + size_t scaled_change = scale_by_gen_gc_cost(change, minor_gc_cost()); 1.915 + 1.916 + if (cur_eden + scaled_change > cur_eden) { 1.917 + desired_eden = cur_eden + scaled_change; 1.918 + } 1.919 + 1.920 + _young_gen_change_for_minor_throughput++; 1.921 + 1.922 + if (PrintAdaptiveSizePolicy && Verbose) { 1.923 + gclog_or_tty->print_cr( 1.924 + "CMSAdaptiveSizePolicy::adjust_eden_for_throughput " 1.925 + "adjusting eden for throughput. " 1.926 + " starting eden size " SIZE_FORMAT 1.927 + " increased eden size " SIZE_FORMAT 1.928 + " eden delta " SIZE_FORMAT, 1.929 + cur_eden, desired_eden, scaled_change); 1.930 + } 1.931 + 1.932 + return desired_eden; 1.933 +} 1.934 + 1.935 +size_t CMSAdaptiveSizePolicy::adjust_eden_for_footprint(size_t cur_eden) { 1.936 + 1.937 + set_decrease_for_footprint(decrease_young_gen_for_footprint_true); 1.938 + 1.939 + size_t change = eden_decrement(cur_eden); 1.940 + size_t desired_eden_size = cur_eden - change; 1.941 + 1.942 + if (PrintAdaptiveSizePolicy && Verbose) { 1.943 + gclog_or_tty->print_cr( 1.944 + "CMSAdaptiveSizePolicy::adjust_eden_for_footprint " 1.945 + "adjusting eden for footprint. " 1.946 + " starting eden size " SIZE_FORMAT 1.947 + " reduced eden size " SIZE_FORMAT 1.948 + " eden delta " SIZE_FORMAT, 1.949 + cur_eden, desired_eden_size, change); 1.950 + } 1.951 + return desired_eden_size; 1.952 +} 1.953 + 1.954 +// The eden and promo versions should be combined if possible. 1.955 +// They are the same except that the sizes of the decrement 1.956 +// and increment are different for eden and promo. 1.957 +size_t CMSAdaptiveSizePolicy::eden_decrement_aligned_down(size_t cur_eden) { 1.958 + size_t delta = eden_decrement(cur_eden); 1.959 + return align_size_down(delta, generation_alignment()); 1.960 +} 1.961 + 1.962 +size_t CMSAdaptiveSizePolicy::eden_increment_aligned_up(size_t cur_eden) { 1.963 + size_t delta = eden_increment(cur_eden); 1.964 + return align_size_up(delta, generation_alignment()); 1.965 +} 1.966 + 1.967 +size_t CMSAdaptiveSizePolicy::promo_decrement_aligned_down(size_t cur_promo) { 1.968 + size_t delta = promo_decrement(cur_promo); 1.969 + return align_size_down(delta, generation_alignment()); 1.970 +} 1.971 + 1.972 +size_t CMSAdaptiveSizePolicy::promo_increment_aligned_up(size_t cur_promo) { 1.973 + size_t delta = promo_increment(cur_promo); 1.974 + return align_size_up(delta, generation_alignment()); 1.975 +} 1.976 + 1.977 + 1.978 +void CMSAdaptiveSizePolicy::compute_eden_space_size(size_t cur_eden, 1.979 + size_t max_eden_size) 1.980 +{ 1.981 + size_t desired_eden_size = cur_eden; 1.982 + size_t eden_limit = max_eden_size; 1.983 + 1.984 + // Printout input 1.985 + if (PrintGC && PrintAdaptiveSizePolicy) { 1.986 + gclog_or_tty->print_cr( 1.987 + "CMSAdaptiveSizePolicy::compute_eden_space_size: " 1.988 + "cur_eden " SIZE_FORMAT, 1.989 + cur_eden); 1.990 + } 1.991 + 1.992 + // Used for diagnostics 1.993 + clear_generation_free_space_flags(); 1.994 + 1.995 + if (_avg_minor_pause->padded_average() > gc_pause_goal_sec()) { 1.996 + if (minor_pause_young_estimator()->decrement_will_decrease()) { 1.997 + // If the minor pause is too long, shrink the young gen. 1.998 + set_change_young_gen_for_min_pauses( 1.999 + decrease_young_gen_for_min_pauses_true); 1.1000 + desired_eden_size = adjust_eden_for_pause_time(desired_eden_size); 1.1001 + } 1.1002 + } else if ((avg_remark_pause()->padded_average() > gc_pause_goal_sec()) || 1.1003 + (avg_initial_pause()->padded_average() > gc_pause_goal_sec())) { 1.1004 + // The remark or initial pauses are not meeting the goal. Should 1.1005 + // the generation be shrunk? 1.1006 + if (get_and_clear_first_after_collection() && 1.1007 + ((avg_remark_pause()->padded_average() > gc_pause_goal_sec() && 1.1008 + remark_pause_young_estimator()->decrement_will_decrease()) || 1.1009 + (avg_initial_pause()->padded_average() > gc_pause_goal_sec() && 1.1010 + initial_pause_young_estimator()->decrement_will_decrease()))) { 1.1011 + 1.1012 + set_change_young_gen_for_maj_pauses( 1.1013 + decrease_young_gen_for_maj_pauses_true); 1.1014 + 1.1015 + // If the remark or initial pause is too long and this is the 1.1016 + // first young gen collection after a cms collection, shrink 1.1017 + // the young gen. 1.1018 + desired_eden_size = adjust_eden_for_pause_time(desired_eden_size); 1.1019 + } 1.1020 + // If not the first young gen collection after a cms collection, 1.1021 + // don't do anything. In this case an adjustment has already 1.1022 + // been made and the results of the adjustment has not yet been 1.1023 + // measured. 1.1024 + } else if ((minor_gc_cost() >= 0.0) && 1.1025 + (adjusted_mutator_cost() < _throughput_goal)) { 1.1026 + desired_eden_size = adjust_eden_for_throughput(desired_eden_size); 1.1027 + } else { 1.1028 + desired_eden_size = adjust_eden_for_footprint(desired_eden_size); 1.1029 + } 1.1030 + 1.1031 + if (PrintGC && PrintAdaptiveSizePolicy) { 1.1032 + gclog_or_tty->print_cr( 1.1033 + "CMSAdaptiveSizePolicy::compute_eden_space_size limits:" 1.1034 + " desired_eden_size: " SIZE_FORMAT 1.1035 + " old_eden_size: " SIZE_FORMAT, 1.1036 + desired_eden_size, cur_eden); 1.1037 + } 1.1038 + 1.1039 + set_eden_size(desired_eden_size); 1.1040 +} 1.1041 + 1.1042 +size_t CMSAdaptiveSizePolicy::adjust_promo_for_pause_time(size_t cur_promo) { 1.1043 + size_t change = 0; 1.1044 + size_t desired_promo = cur_promo; 1.1045 + // Move this test up to caller like the adjust_eden_for_pause_time() 1.1046 + // call. 1.1047 + if ((AdaptiveSizePausePolicy == 0) && 1.1048 + ((avg_remark_pause()->padded_average() > gc_pause_goal_sec()) || 1.1049 + (avg_initial_pause()->padded_average() > gc_pause_goal_sec()))) { 1.1050 + set_change_old_gen_for_maj_pauses(decrease_old_gen_for_maj_pauses_true); 1.1051 + change = promo_decrement_aligned_down(cur_promo); 1.1052 + desired_promo = cur_promo - change; 1.1053 + } else if ((AdaptiveSizePausePolicy > 0) && 1.1054 + (((avg_remark_pause()->padded_average() > gc_pause_goal_sec()) && 1.1055 + remark_pause_old_estimator()->decrement_will_decrease()) || 1.1056 + ((avg_initial_pause()->padded_average() > gc_pause_goal_sec()) && 1.1057 + initial_pause_old_estimator()->decrement_will_decrease()))) { 1.1058 + set_change_old_gen_for_maj_pauses(decrease_old_gen_for_maj_pauses_true); 1.1059 + change = promo_decrement_aligned_down(cur_promo); 1.1060 + desired_promo = cur_promo - change; 1.1061 + } 1.1062 + 1.1063 + if ((change != 0) &&PrintAdaptiveSizePolicy && Verbose) { 1.1064 + gclog_or_tty->print_cr( 1.1065 + "CMSAdaptiveSizePolicy::adjust_promo_for_pause_time " 1.1066 + "adjusting promo for pause time. " 1.1067 + " starting promo size " SIZE_FORMAT 1.1068 + " reduced promo size " SIZE_FORMAT 1.1069 + " promo delta " SIZE_FORMAT, 1.1070 + cur_promo, desired_promo, change); 1.1071 + } 1.1072 + 1.1073 + return desired_promo; 1.1074 +} 1.1075 + 1.1076 +// Try to share this with PS. 1.1077 +size_t CMSAdaptiveSizePolicy::scale_by_gen_gc_cost(size_t base_change, 1.1078 + double gen_gc_cost) { 1.1079 + 1.1080 + // Calculate the change to use for the tenured gen. 1.1081 + size_t scaled_change = 0; 1.1082 + // Can the increment to the generation be scaled? 1.1083 + if (gc_cost() >= 0.0 && gen_gc_cost >= 0.0) { 1.1084 + double scale_by_ratio = gen_gc_cost / gc_cost(); 1.1085 + scaled_change = 1.1086 + (size_t) (scale_by_ratio * (double) base_change); 1.1087 + if (PrintAdaptiveSizePolicy && Verbose) { 1.1088 + gclog_or_tty->print_cr( 1.1089 + "Scaled tenured increment: " SIZE_FORMAT " by %f down to " 1.1090 + SIZE_FORMAT, 1.1091 + base_change, scale_by_ratio, scaled_change); 1.1092 + } 1.1093 + } else if (gen_gc_cost >= 0.0) { 1.1094 + // Scaling is not going to work. If the major gc time is the 1.1095 + // larger than the other GC costs, give it a full increment. 1.1096 + if (gen_gc_cost >= (gc_cost() - gen_gc_cost)) { 1.1097 + scaled_change = base_change; 1.1098 + } 1.1099 + } else { 1.1100 + // Don't expect to get here but it's ok if it does 1.1101 + // in the product build since the delta will be 0 1.1102 + // and nothing will change. 1.1103 + assert(false, "Unexpected value for gc costs"); 1.1104 + } 1.1105 + 1.1106 + return scaled_change; 1.1107 +} 1.1108 + 1.1109 +size_t CMSAdaptiveSizePolicy::adjust_promo_for_throughput(size_t cur_promo) { 1.1110 + 1.1111 + size_t desired_promo = cur_promo; 1.1112 + 1.1113 + set_change_old_gen_for_throughput(increase_old_gen_for_throughput_true); 1.1114 + 1.1115 + size_t change = promo_increment_aligned_up(cur_promo); 1.1116 + size_t scaled_change = scale_by_gen_gc_cost(change, major_gc_cost()); 1.1117 + 1.1118 + if (cur_promo + scaled_change > cur_promo) { 1.1119 + desired_promo = cur_promo + scaled_change; 1.1120 + } 1.1121 + 1.1122 + _old_gen_change_for_major_throughput++; 1.1123 + 1.1124 + if (PrintAdaptiveSizePolicy && Verbose) { 1.1125 + gclog_or_tty->print_cr( 1.1126 + "CMSAdaptiveSizePolicy::adjust_promo_for_throughput " 1.1127 + "adjusting promo for throughput. " 1.1128 + " starting promo size " SIZE_FORMAT 1.1129 + " increased promo size " SIZE_FORMAT 1.1130 + " promo delta " SIZE_FORMAT, 1.1131 + cur_promo, desired_promo, scaled_change); 1.1132 + } 1.1133 + 1.1134 + return desired_promo; 1.1135 +} 1.1136 + 1.1137 +size_t CMSAdaptiveSizePolicy::adjust_promo_for_footprint(size_t cur_promo, 1.1138 + size_t cur_eden) { 1.1139 + 1.1140 + set_decrease_for_footprint(decrease_young_gen_for_footprint_true); 1.1141 + 1.1142 + size_t change = promo_decrement(cur_promo); 1.1143 + size_t desired_promo_size = cur_promo - change; 1.1144 + 1.1145 + if (PrintAdaptiveSizePolicy && Verbose) { 1.1146 + gclog_or_tty->print_cr( 1.1147 + "CMSAdaptiveSizePolicy::adjust_promo_for_footprint " 1.1148 + "adjusting promo for footprint. " 1.1149 + " starting promo size " SIZE_FORMAT 1.1150 + " reduced promo size " SIZE_FORMAT 1.1151 + " promo delta " SIZE_FORMAT, 1.1152 + cur_promo, desired_promo_size, change); 1.1153 + } 1.1154 + return desired_promo_size; 1.1155 +} 1.1156 + 1.1157 +void CMSAdaptiveSizePolicy::compute_tenured_generation_free_space( 1.1158 + size_t cur_tenured_free, 1.1159 + size_t max_tenured_available, 1.1160 + size_t cur_eden) { 1.1161 + // This can be bad if the desired value grows/shrinks without 1.1162 + // any connection to the read free space 1.1163 + size_t desired_promo_size = promo_size(); 1.1164 + size_t tenured_limit = max_tenured_available; 1.1165 + 1.1166 + // Printout input 1.1167 + if (PrintGC && PrintAdaptiveSizePolicy) { 1.1168 + gclog_or_tty->print_cr( 1.1169 + "CMSAdaptiveSizePolicy::compute_tenured_generation_free_space: " 1.1170 + "cur_tenured_free " SIZE_FORMAT 1.1171 + " max_tenured_available " SIZE_FORMAT, 1.1172 + cur_tenured_free, max_tenured_available); 1.1173 + } 1.1174 + 1.1175 + // Used for diagnostics 1.1176 + clear_generation_free_space_flags(); 1.1177 + 1.1178 + set_decide_at_full_gc(decide_at_full_gc_true); 1.1179 + if (avg_remark_pause()->padded_average() > gc_pause_goal_sec() || 1.1180 + avg_initial_pause()->padded_average() > gc_pause_goal_sec()) { 1.1181 + desired_promo_size = adjust_promo_for_pause_time(cur_tenured_free); 1.1182 + } else if (avg_minor_pause()->padded_average() > gc_pause_goal_sec()) { 1.1183 + // Nothing to do since the minor collections are too large and 1.1184 + // this method only deals with the cms generation. 1.1185 + } else if ((cms_gc_cost() >= 0.0) && 1.1186 + (adjusted_mutator_cost() < _throughput_goal)) { 1.1187 + desired_promo_size = adjust_promo_for_throughput(cur_tenured_free); 1.1188 + } else { 1.1189 + desired_promo_size = adjust_promo_for_footprint(cur_tenured_free, 1.1190 + cur_eden); 1.1191 + } 1.1192 + 1.1193 + if (PrintGC && PrintAdaptiveSizePolicy) { 1.1194 + gclog_or_tty->print_cr( 1.1195 + "CMSAdaptiveSizePolicy::compute_tenured_generation_free_space limits:" 1.1196 + " desired_promo_size: " SIZE_FORMAT 1.1197 + " old_promo_size: " SIZE_FORMAT, 1.1198 + desired_promo_size, cur_tenured_free); 1.1199 + } 1.1200 + 1.1201 + set_promo_size(desired_promo_size); 1.1202 +} 1.1203 + 1.1204 +uint CMSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold( 1.1205 + bool is_survivor_overflow, 1.1206 + uint tenuring_threshold, 1.1207 + size_t survivor_limit) { 1.1208 + assert(survivor_limit >= generation_alignment(), 1.1209 + "survivor_limit too small"); 1.1210 + assert((size_t)align_size_down(survivor_limit, generation_alignment()) 1.1211 + == survivor_limit, "survivor_limit not aligned"); 1.1212 + 1.1213 + // Change UsePSAdaptiveSurvivorSizePolicy -> UseAdaptiveSurvivorSizePolicy? 1.1214 + if (!UsePSAdaptiveSurvivorSizePolicy || 1.1215 + !young_gen_policy_is_ready()) { 1.1216 + return tenuring_threshold; 1.1217 + } 1.1218 + 1.1219 + // We'll decide whether to increase or decrease the tenuring 1.1220 + // threshold based partly on the newly computed survivor size 1.1221 + // (if we hit the maximum limit allowed, we'll always choose to 1.1222 + // decrement the threshold). 1.1223 + bool incr_tenuring_threshold = false; 1.1224 + bool decr_tenuring_threshold = false; 1.1225 + 1.1226 + set_decrement_tenuring_threshold_for_gc_cost(false); 1.1227 + set_increment_tenuring_threshold_for_gc_cost(false); 1.1228 + set_decrement_tenuring_threshold_for_survivor_limit(false); 1.1229 + 1.1230 + if (!is_survivor_overflow) { 1.1231 + // Keep running averages on how much survived 1.1232 + 1.1233 + // We use the tenuring threshold to equalize the cost of major 1.1234 + // and minor collections. 1.1235 + // ThresholdTolerance is used to indicate how sensitive the 1.1236 + // tenuring threshold is to differences in cost betweent the 1.1237 + // collection types. 1.1238 + 1.1239 + // Get the times of interest. This involves a little work, so 1.1240 + // we cache the values here. 1.1241 + const double major_cost = major_gc_cost(); 1.1242 + const double minor_cost = minor_gc_cost(); 1.1243 + 1.1244 + if (minor_cost > major_cost * _threshold_tolerance_percent) { 1.1245 + // Minor times are getting too long; lower the threshold so 1.1246 + // less survives and more is promoted. 1.1247 + decr_tenuring_threshold = true; 1.1248 + set_decrement_tenuring_threshold_for_gc_cost(true); 1.1249 + } else if (major_cost > minor_cost * _threshold_tolerance_percent) { 1.1250 + // Major times are too long, so we want less promotion. 1.1251 + incr_tenuring_threshold = true; 1.1252 + set_increment_tenuring_threshold_for_gc_cost(true); 1.1253 + } 1.1254 + 1.1255 + } else { 1.1256 + // Survivor space overflow occurred, so promoted and survived are 1.1257 + // not accurate. We'll make our best guess by combining survived 1.1258 + // and promoted and count them as survivors. 1.1259 + // 1.1260 + // We'll lower the tenuring threshold to see if we can correct 1.1261 + // things. Also, set the survivor size conservatively. We're 1.1262 + // trying to avoid many overflows from occurring if defnew size 1.1263 + // is just too small. 1.1264 + 1.1265 + decr_tenuring_threshold = true; 1.1266 + } 1.1267 + 1.1268 + // The padded average also maintains a deviation from the average; 1.1269 + // we use this to see how good of an estimate we have of what survived. 1.1270 + // We're trying to pad the survivor size as little as possible without 1.1271 + // overflowing the survivor spaces. 1.1272 + size_t target_size = align_size_up((size_t)_avg_survived->padded_average(), 1.1273 + generation_alignment()); 1.1274 + target_size = MAX2(target_size, generation_alignment()); 1.1275 + 1.1276 + if (target_size > survivor_limit) { 1.1277 + // Target size is bigger than we can handle. Let's also reduce 1.1278 + // the tenuring threshold. 1.1279 + target_size = survivor_limit; 1.1280 + decr_tenuring_threshold = true; 1.1281 + set_decrement_tenuring_threshold_for_survivor_limit(true); 1.1282 + } 1.1283 + 1.1284 + // Finally, increment or decrement the tenuring threshold, as decided above. 1.1285 + // We test for decrementing first, as we might have hit the target size 1.1286 + // limit. 1.1287 + if (decr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) { 1.1288 + if (tenuring_threshold > 1) { 1.1289 + tenuring_threshold--; 1.1290 + } 1.1291 + } else if (incr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) { 1.1292 + if (tenuring_threshold < MaxTenuringThreshold) { 1.1293 + tenuring_threshold++; 1.1294 + } 1.1295 + } 1.1296 + 1.1297 + // We keep a running average of the amount promoted which is used 1.1298 + // to decide when we should collect the old generation (when 1.1299 + // the amount of old gen free space is less than what we expect to 1.1300 + // promote). 1.1301 + 1.1302 + if (PrintAdaptiveSizePolicy) { 1.1303 + // A little more detail if Verbose is on 1.1304 + GenCollectedHeap* gch = GenCollectedHeap::heap(); 1.1305 + if (Verbose) { 1.1306 + gclog_or_tty->print( " avg_survived: %f" 1.1307 + " avg_deviation: %f", 1.1308 + _avg_survived->average(), 1.1309 + _avg_survived->deviation()); 1.1310 + } 1.1311 + 1.1312 + gclog_or_tty->print( " avg_survived_padded_avg: %f", 1.1313 + _avg_survived->padded_average()); 1.1314 + 1.1315 + if (Verbose) { 1.1316 + gclog_or_tty->print( " avg_promoted_avg: %f" 1.1317 + " avg_promoted_dev: %f", 1.1318 + gch->gc_stats(1)->avg_promoted()->average(), 1.1319 + gch->gc_stats(1)->avg_promoted()->deviation()); 1.1320 + } 1.1321 + 1.1322 + gclog_or_tty->print( " avg_promoted_padded_avg: %f" 1.1323 + " avg_pretenured_padded_avg: %f" 1.1324 + " tenuring_thresh: %u" 1.1325 + " target_size: " SIZE_FORMAT 1.1326 + " survivor_limit: " SIZE_FORMAT, 1.1327 + gch->gc_stats(1)->avg_promoted()->padded_average(), 1.1328 + _avg_pretenured->padded_average(), 1.1329 + tenuring_threshold, target_size, survivor_limit); 1.1330 + gclog_or_tty->cr(); 1.1331 + } 1.1332 + 1.1333 + set_survivor_size(target_size); 1.1334 + 1.1335 + return tenuring_threshold; 1.1336 +} 1.1337 + 1.1338 +bool CMSAdaptiveSizePolicy::get_and_clear_first_after_collection() { 1.1339 + bool result = _first_after_collection; 1.1340 + _first_after_collection = false; 1.1341 + return result; 1.1342 +} 1.1343 + 1.1344 +bool CMSAdaptiveSizePolicy::print_adaptive_size_policy_on( 1.1345 + outputStream* st) const { 1.1346 + 1.1347 + if (!UseAdaptiveSizePolicy) return false; 1.1348 + 1.1349 + GenCollectedHeap* gch = GenCollectedHeap::heap(); 1.1350 + Generation* gen0 = gch->get_gen(0); 1.1351 + DefNewGeneration* def_new = gen0->as_DefNewGeneration(); 1.1352 + return 1.1353 + AdaptiveSizePolicy::print_adaptive_size_policy_on( 1.1354 + st, 1.1355 + def_new->tenuring_threshold()); 1.1356 +}