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), |
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 |
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; |