comparison src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @ 1973:631f79e71e90

6974966: G1: unnecessary direct-to-old allocations Summary: This change revamps the slow allocation path of G1. Improvements include the following: a) Allocations directly to old regions are now totally banned. G1 now only allows allocations out of young regions (with the only exception being humongous regions). b) The thread that allocates a new region (which is now guaranteed to be young) does not dirty all its cards. Each thread that successfully allocates out of a young region is now responsible for dirtying the cards that corresponding to the "block" that just got allocated. c) allocate_new_tlab() and mem_allocate() are now implemented differently and TLAB allocations are only done by allocate_new_tlab(). d) If a thread schedules an evacuation pause in order to satisfy an allocation request, it will perform the allocation at the end of the safepoint so that the thread that initiated the GC also gets "first pick" of any space made available by the GC. e) If a thread is unable to allocate a humongous object it will schedule an evacuation pause in case it reclaims enough regions so that the humongous allocation can be satisfied aftewards. f) The G1 policy is more careful to set the young list target length to be the survivor number +1. g) Lots of code tidy up, removal, refactoring to make future changes easier. Reviewed-by: johnc, ysr
author tonyp
date Tue, 24 Aug 2010 17:24:33 -0400
parents f95d63e2154a
children 016a3628c885
comparison
equal deleted inserted replaced
1972:f95d63e2154a 1973:631f79e71e90
456 456
457 if (_alloc_rate_ms_seq->num() > 3) { 457 if (_alloc_rate_ms_seq->num() > 3) {
458 double now_sec = os::elapsedTime(); 458 double now_sec = os::elapsedTime();
459 double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0; 459 double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0;
460 double alloc_rate_ms = predict_alloc_rate_ms(); 460 double alloc_rate_ms = predict_alloc_rate_ms();
461 int min_regions = (int) ceil(alloc_rate_ms * when_ms); 461 size_t min_regions = (size_t) ceil(alloc_rate_ms * when_ms);
462 int current_region_num = (int) _g1->young_list()->length(); 462 size_t current_region_num = _g1->young_list()->length();
463 _young_list_min_length = min_regions + current_region_num; 463 _young_list_min_length = min_regions + current_region_num;
464 } 464 }
465 } 465 }
466 466
467 void G1CollectorPolicy::calculate_young_list_target_length() { 467 void G1CollectorPolicy::calculate_young_list_target_length() {
471 } else { 471 } else {
472 if (full_young_gcs()) 472 if (full_young_gcs())
473 _young_list_target_length = _young_list_fixed_length; 473 _young_list_target_length = _young_list_fixed_length;
474 else 474 else
475 _young_list_target_length = _young_list_fixed_length / 2; 475 _young_list_target_length = _young_list_fixed_length / 2;
476 476 }
477 _young_list_target_length = MAX2(_young_list_target_length, (size_t)1); 477
478 } 478 // Make sure we allow the application to allocate at least one
479 // region before we need to do a collection again.
480 size_t min_length = _g1->young_list()->length() + 1;
481 _young_list_target_length = MAX2(_young_list_target_length, min_length);
479 calculate_survivors_policy(); 482 calculate_survivors_policy();
480 } 483 }
481 484
482 void G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths) { 485 void G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths) {
483 guarantee( adaptive_young_list_length(), "pre-condition" ); 486 guarantee( adaptive_young_list_length(), "pre-condition" );
566 } 569 }
567 // and we're done! 570 // and we're done!
568 571
569 // we should have at least one region in the target young length 572 // we should have at least one region in the target young length
570 _young_list_target_length = 573 _young_list_target_length =
571 MAX2((size_t) 1, final_young_length + _recorded_survivor_regions); 574 final_young_length + _recorded_survivor_regions;
572 575
573 // let's keep an eye of how long we spend on this calculation 576 // let's keep an eye of how long we spend on this calculation
574 // right now, I assume that we'll print it when we need it; we 577 // right now, I assume that we'll print it when we need it; we
575 // should really adde it to the breakdown of a pause 578 // should really adde it to the breakdown of a pause
576 double end_time_sec = os::elapsedTime(); 579 double end_time_sec = os::elapsedTime();
615 // leave this in for debugging, just in case 618 // leave this in for debugging, just in case
616 gclog_or_tty->print_cr("(partial) setting target to " SIZE_FORMAT 619 gclog_or_tty->print_cr("(partial) setting target to " SIZE_FORMAT
617 _young_list_min_length); 620 _young_list_min_length);
618 #endif // TRACE_CALC_YOUNG_LENGTH 621 #endif // TRACE_CALC_YOUNG_LENGTH
619 // we'll do the pause as soon as possible by choosing the minimum 622 // we'll do the pause as soon as possible by choosing the minimum
620 _young_list_target_length = 623 _young_list_target_length = _young_list_min_length;
621 MAX2(_young_list_min_length, (size_t) 1);
622 } 624 }
623 625
624 _rs_lengths_prediction = rs_lengths; 626 _rs_lengths_prediction = rs_lengths;
625 } 627 }
626 628
799 _free_regions_at_end_of_collection = _g1->free_regions(); 801 _free_regions_at_end_of_collection = _g1->free_regions();
800 // Reset survivors SurvRateGroup. 802 // Reset survivors SurvRateGroup.
801 _survivor_surv_rate_group->reset(); 803 _survivor_surv_rate_group->reset();
802 calculate_young_list_min_length(); 804 calculate_young_list_min_length();
803 calculate_young_list_target_length(); 805 calculate_young_list_target_length();
804 } 806 }
805 807
806 void G1CollectorPolicy::record_before_bytes(size_t bytes) { 808 void G1CollectorPolicy::record_before_bytes(size_t bytes) {
807 _bytes_in_to_space_before_gc += bytes; 809 _bytes_in_to_space_before_gc += bytes;
808 } 810 }
809 811
822 gclog_or_tty->print("[GC pause"); 824 gclog_or_tty->print("[GC pause");
823 if (in_young_gc_mode()) 825 if (in_young_gc_mode())
824 gclog_or_tty->print(" (%s)", full_young_gcs() ? "young" : "partial"); 826 gclog_or_tty->print(" (%s)", full_young_gcs() ? "young" : "partial");
825 } 827 }
826 828
827 assert(_g1->used_regions() == _g1->recalculate_used_regions(), 829 assert(_g1->used() == _g1->recalculate_used(),
828 "sanity"); 830 err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT,
829 assert(_g1->used() == _g1->recalculate_used(), "sanity"); 831 _g1->used(), _g1->recalculate_used()));
830 832
831 double s_w_t_ms = (start_time_sec - _stop_world_start) * 1000.0; 833 double s_w_t_ms = (start_time_sec - _stop_world_start) * 1000.0;
832 _all_stop_world_times_ms->add(s_w_t_ms); 834 _all_stop_world_times_ms->add(s_w_t_ms);
833 _stop_world_start = 0.0; 835 _stop_world_start = 0.0;
834 836
2264 _short_lived_surv_rate_group->print_surv_rate_summary(); 2266 _short_lived_surv_rate_group->print_surv_rate_summary();
2265 // add this call for any other surv rate groups 2267 // add this call for any other surv rate groups
2266 #endif // PRODUCT 2268 #endif // PRODUCT
2267 } 2269 }
2268 2270
2269 bool 2271 void
2270 G1CollectorPolicy::should_add_next_region_to_young_list() { 2272 G1CollectorPolicy::update_region_num(bool young) {
2271 assert(in_young_gc_mode(), "should be in young GC mode"); 2273 if (young) {
2272 bool ret;
2273 size_t young_list_length = _g1->young_list()->length();
2274 size_t young_list_max_length = _young_list_target_length;
2275 if (G1FixedEdenSize) {
2276 young_list_max_length -= _max_survivor_regions;
2277 }
2278 if (young_list_length < young_list_max_length) {
2279 ret = true;
2280 ++_region_num_young; 2274 ++_region_num_young;
2281 } else { 2275 } else {
2282 ret = false;
2283 ++_region_num_tenured; 2276 ++_region_num_tenured;
2284 } 2277 }
2285
2286 return ret;
2287 } 2278 }
2288 2279
2289 #ifndef PRODUCT 2280 #ifndef PRODUCT
2290 // for debugging, bit of a hack... 2281 // for debugging, bit of a hack...
2291 static char* 2282 static char*
2323 _tenuring_threshold = MaxTenuringThreshold; 2314 _tenuring_threshold = MaxTenuringThreshold;
2324 } else { 2315 } else {
2325 _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold( 2316 _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(
2326 HeapRegion::GrainWords * _max_survivor_regions); 2317 HeapRegion::GrainWords * _max_survivor_regions);
2327 } 2318 }
2328 }
2329
2330 bool
2331 G1CollectorPolicy_BestRegionsFirst::should_do_collection_pause(size_t
2332 word_size) {
2333 assert(_g1->regions_accounted_for(), "Region leakage!");
2334 double max_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
2335
2336 size_t young_list_length = _g1->young_list()->length();
2337 size_t young_list_max_length = _young_list_target_length;
2338 if (G1FixedEdenSize) {
2339 young_list_max_length -= _max_survivor_regions;
2340 }
2341 bool reached_target_length = young_list_length >= young_list_max_length;
2342
2343 if (in_young_gc_mode()) {
2344 if (reached_target_length) {
2345 assert( young_list_length > 0 && _g1->young_list()->length() > 0,
2346 "invariant" );
2347 return true;
2348 }
2349 } else {
2350 guarantee( false, "should not reach here" );
2351 }
2352
2353 return false;
2354 } 2319 }
2355 2320
2356 #ifndef PRODUCT 2321 #ifndef PRODUCT
2357 class HRSortIndexIsOKClosure: public HeapRegionClosure { 2322 class HRSortIndexIsOKClosure: public HeapRegionClosure {
2358 CollectionSetChooser* _chooser; 2323 CollectionSetChooser* _chooser;