comparison src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @ 4729:1cbe7978b021

7113021: G1: automatically enable young gen size auto-tuning when -Xms==-Xmx Summary: Use a percentage of -Xms as min and another percentage of -Xmx as max for the young gen size Reviewed-by: tonyp, johnc
author brutisso
date Wed, 21 Dec 2011 22:13:31 +0100
parents 441e946dc1af
children 2ace1c4ee8da
comparison
equal deleted inserted replaced
4728:441e946dc1af 4729:1cbe7978b021
134 _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), 134 _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
135 _all_pause_times_ms(new NumberSeq()), 135 _all_pause_times_ms(new NumberSeq()),
136 _stop_world_start(0.0), 136 _stop_world_start(0.0),
137 _all_stop_world_times_ms(new NumberSeq()), 137 _all_stop_world_times_ms(new NumberSeq()),
138 _all_yield_times_ms(new NumberSeq()), 138 _all_yield_times_ms(new NumberSeq()),
139 _using_new_ratio_calculations(false),
140 139
141 _summary(new Summary()), 140 _summary(new Summary()),
142 141
143 _cur_clear_ct_time_ms(0.0), 142 _cur_clear_ct_time_ms(0.0),
144 _mark_closure_time_ms(0.0), 143 _mark_closure_time_ms(0.0),
407 // for the first time during initialization. 406 // for the first time during initialization.
408 _reserve_regions = 0; 407 _reserve_regions = 0;
409 408
410 initialize_all(); 409 initialize_all();
411 _collectionSetChooser = new CollectionSetChooser(); 410 _collectionSetChooser = new CollectionSetChooser();
412 } 411 _young_gen_sizer = new G1YoungGenSizer(); // Must be after call to initialize_flags
413
414 // Increment "i", mod "len"
415 static void inc_mod(int& i, int len) {
416 i++; if (i == len) i = 0;
417 } 412 }
418 413
419 void G1CollectorPolicy::initialize_flags() { 414 void G1CollectorPolicy::initialize_flags() {
420 set_min_alignment(HeapRegion::GrainBytes); 415 set_min_alignment(HeapRegion::GrainBytes);
421 set_max_alignment(GenRemSet::max_alignment_constraint(rem_set_name())); 416 set_max_alignment(GenRemSet::max_alignment_constraint(rem_set_name()));
423 vm_exit_during_initialization("Invalid survivor ratio specified"); 418 vm_exit_during_initialization("Invalid survivor ratio specified");
424 } 419 }
425 CollectorPolicy::initialize_flags(); 420 CollectorPolicy::initialize_flags();
426 } 421 }
427 422
428 // The easiest way to deal with the parsing of the NewSize / 423 G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true) {
429 // MaxNewSize / etc. parameteres is to re-use the code in the 424 assert(G1DefaultMinNewGenPercent <= G1DefaultMaxNewGenPercent, "Min larger than max");
430 // TwoGenerationCollectorPolicy class. This is similar to what 425 assert(G1DefaultMinNewGenPercent > 0 && G1DefaultMinNewGenPercent < 100, "Min out of bounds");
431 // ParallelScavenge does with its GenerationSizer class (see 426 assert(G1DefaultMaxNewGenPercent > 0 && G1DefaultMaxNewGenPercent < 100, "Max out of bounds");
432 // ParallelScavengeHeap::initialize()). We might change this in the
433 // future, but it's a good start.
434 class G1YoungGenSizer : public TwoGenerationCollectorPolicy {
435 private:
436 size_t size_to_region_num(size_t byte_size) {
437 return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
438 }
439
440 public:
441 G1YoungGenSizer() {
442 initialize_flags();
443 initialize_size_info();
444 }
445 size_t min_young_region_num() {
446 return size_to_region_num(_min_gen0_size);
447 }
448 size_t initial_young_region_num() {
449 return size_to_region_num(_initial_gen0_size);
450 }
451 size_t max_young_region_num() {
452 return size_to_region_num(_max_gen0_size);
453 }
454 };
455
456 void G1CollectorPolicy::update_young_list_size_using_newratio(size_t number_of_heap_regions) {
457 assert(number_of_heap_regions > 0, "Heap must be initialized");
458 size_t young_size = number_of_heap_regions / (NewRatio + 1);
459 _min_desired_young_length = young_size;
460 _max_desired_young_length = young_size;
461 }
462
463 void G1CollectorPolicy::init() {
464 // Set aside an initial future to_space.
465 _g1 = G1CollectedHeap::heap();
466
467 assert(Heap_lock->owned_by_self(), "Locking discipline.");
468
469 initialize_gc_policy_counters();
470
471 G1YoungGenSizer sizer;
472 _min_desired_young_length = sizer.min_young_region_num();
473 _max_desired_young_length = sizer.max_young_region_num();
474 427
475 if (FLAG_IS_CMDLINE(NewRatio)) { 428 if (FLAG_IS_CMDLINE(NewRatio)) {
476 if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) { 429 if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) {
477 warning("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio"); 430 warning("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio");
478 } else { 431 } else {
479 // Treat NewRatio as a fixed size that is only recalculated when the heap size changes 432 _sizer_kind = SizerNewRatio;
480 update_young_list_size_using_newratio(_g1->n_regions()); 433 _adaptive_size = false;
481 _using_new_ratio_calculations = true; 434 return;
482 } 435 }
436 }
437
438 if (FLAG_IS_CMDLINE(NewSize)) {
439 _min_desired_young_length = MAX2((size_t) 1, NewSize / HeapRegion::GrainBytes);
440 if (FLAG_IS_CMDLINE(MaxNewSize)) {
441 _max_desired_young_length = MAX2((size_t) 1, MaxNewSize / HeapRegion::GrainBytes);
442 _sizer_kind = SizerMaxAndNewSize;
443 _adaptive_size = _min_desired_young_length == _max_desired_young_length;
444 } else {
445 _sizer_kind = SizerNewSizeOnly;
446 }
447 } else if (FLAG_IS_CMDLINE(MaxNewSize)) {
448 _max_desired_young_length = MAX2((size_t) 1, MaxNewSize / HeapRegion::GrainBytes);
449 _sizer_kind = SizerMaxNewSizeOnly;
450 }
451 }
452
453 size_t G1YoungGenSizer::calculate_default_min_length(size_t new_number_of_heap_regions) {
454 size_t default_value = (new_number_of_heap_regions * G1DefaultMinNewGenPercent) / 100;
455 return MAX2((size_t)1, default_value);
456 }
457
458 size_t G1YoungGenSizer::calculate_default_max_length(size_t new_number_of_heap_regions) {
459 size_t default_value = (new_number_of_heap_regions * G1DefaultMaxNewGenPercent) / 100;
460 return MAX2((size_t)1, default_value);
461 }
462
463 void G1YoungGenSizer::heap_size_changed(size_t new_number_of_heap_regions) {
464 assert(new_number_of_heap_regions > 0, "Heap must be initialized");
465
466 switch (_sizer_kind) {
467 case SizerDefaults:
468 _min_desired_young_length = calculate_default_min_length(new_number_of_heap_regions);
469 _max_desired_young_length = calculate_default_max_length(new_number_of_heap_regions);
470 break;
471 case SizerNewSizeOnly:
472 _max_desired_young_length = calculate_default_max_length(new_number_of_heap_regions);
473 _max_desired_young_length = MAX2(_min_desired_young_length, _max_desired_young_length);
474 break;
475 case SizerMaxNewSizeOnly:
476 _min_desired_young_length = calculate_default_min_length(new_number_of_heap_regions);
477 _min_desired_young_length = MIN2(_min_desired_young_length, _max_desired_young_length);
478 break;
479 case SizerMaxAndNewSize:
480 // Do nothing. Values set on the command line, don't update them at runtime.
481 break;
482 case SizerNewRatio:
483 _min_desired_young_length = new_number_of_heap_regions / (NewRatio + 1);
484 _max_desired_young_length = _min_desired_young_length;
485 break;
486 default:
487 ShouldNotReachHere();
483 } 488 }
484 489
485 assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values"); 490 assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values");
486 491 }
487 set_adaptive_young_list_length(_min_desired_young_length < _max_desired_young_length); 492
493 void G1CollectorPolicy::init() {
494 // Set aside an initial future to_space.
495 _g1 = G1CollectedHeap::heap();
496
497 assert(Heap_lock->owned_by_self(), "Locking discipline.");
498
499 initialize_gc_policy_counters();
500
488 if (adaptive_young_list_length()) { 501 if (adaptive_young_list_length()) {
489 _young_list_fixed_length = 0; 502 _young_list_fixed_length = 0;
490 } else { 503 } else {
491 assert(_min_desired_young_length == _max_desired_young_length, "Min and max young size differ"); 504 _young_list_fixed_length = _young_gen_sizer->min_desired_young_length();
492 _young_list_fixed_length = _min_desired_young_length;
493 } 505 }
494 _free_regions_at_end_of_collection = _g1->free_regions(); 506 _free_regions_at_end_of_collection = _g1->free_regions();
495 update_young_list_target_length(); 507 update_young_list_target_length();
496 _prev_eden_capacity = _young_list_target_length * HeapRegion::GrainBytes; 508 _prev_eden_capacity = _young_list_target_length * HeapRegion::GrainBytes;
497 509
541 double reserve_regions_d = (double) new_number_of_regions * _reserve_factor; 553 double reserve_regions_d = (double) new_number_of_regions * _reserve_factor;
542 // We use ceiling so that if reserve_regions_d is > 0.0 (but 554 // We use ceiling so that if reserve_regions_d is > 0.0 (but
543 // smaller than 1.0) we'll get 1. 555 // smaller than 1.0) we'll get 1.
544 _reserve_regions = (size_t) ceil(reserve_regions_d); 556 _reserve_regions = (size_t) ceil(reserve_regions_d);
545 557
546 if (_using_new_ratio_calculations) { 558 _young_gen_sizer->heap_size_changed(new_number_of_regions);
547 // -XX:NewRatio was specified so we need to update the
548 // young gen length when the heap size has changed.
549 update_young_list_size_using_newratio(new_number_of_regions);
550 }
551 } 559 }
552 560
553 size_t G1CollectorPolicy::calculate_young_list_desired_min_length( 561 size_t G1CollectorPolicy::calculate_young_list_desired_min_length(
554 size_t base_min_length) { 562 size_t base_min_length) {
555 size_t desired_min_length = 0; 563 size_t desired_min_length = 0;
563 // otherwise we don't have enough info to make the prediction 571 // otherwise we don't have enough info to make the prediction
564 } 572 }
565 } 573 }
566 desired_min_length += base_min_length; 574 desired_min_length += base_min_length;
567 // make sure we don't go below any user-defined minimum bound 575 // make sure we don't go below any user-defined minimum bound
568 return MAX2(_min_desired_young_length, desired_min_length); 576 return MAX2(_young_gen_sizer->min_desired_young_length(), desired_min_length);
569 } 577 }
570 578
571 size_t G1CollectorPolicy::calculate_young_list_desired_max_length() { 579 size_t G1CollectorPolicy::calculate_young_list_desired_max_length() {
572 // Here, we might want to also take into account any additional 580 // Here, we might want to also take into account any additional
573 // constraints (i.e., user-defined minimum bound). Currently, we 581 // constraints (i.e., user-defined minimum bound). Currently, we
574 // effectively don't set this bound. 582 // effectively don't set this bound.
575 return _max_desired_young_length; 583 return _young_gen_sizer->max_desired_young_length();
576 } 584 }
577 585
578 void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) { 586 void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) {
579 if (rs_lengths == (size_t) -1) { 587 if (rs_lengths == (size_t) -1) {
580 // if it's set to the default value (-1), we should predict it; 588 // if it's set to the default value (-1), we should predict it;