279 G1Policy::calculate_young_list_target_length(size_t rs_lengths, |
279 G1Policy::calculate_young_list_target_length(size_t rs_lengths, |
280 uint base_min_length, |
280 uint base_min_length, |
281 uint desired_min_length, |
281 uint desired_min_length, |
282 uint desired_max_length) const { |
282 uint desired_max_length) const { |
283 assert(adaptive_young_list_length(), "pre-condition"); |
283 assert(adaptive_young_list_length(), "pre-condition"); |
284 assert(collector_state()->gcs_are_young(), "only call this for young GCs"); |
284 assert(collector_state()->in_young_only_phase(), "only call this for young GCs"); |
285 |
285 |
286 // In case some edge-condition makes the desired max length too small... |
286 // In case some edge-condition makes the desired max length too small... |
287 if (desired_max_length <= desired_min_length) { |
287 if (desired_max_length <= desired_min_length) { |
288 return desired_min_length; |
288 return desired_min_length; |
289 } |
289 } |
300 |
300 |
301 const double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; |
301 const double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; |
302 const double survivor_regions_evac_time = predict_survivor_regions_evac_time(); |
302 const double survivor_regions_evac_time = predict_survivor_regions_evac_time(); |
303 const size_t pending_cards = _analytics->predict_pending_cards(); |
303 const size_t pending_cards = _analytics->predict_pending_cards(); |
304 const size_t adj_rs_lengths = rs_lengths + _analytics->predict_rs_length_diff(); |
304 const size_t adj_rs_lengths = rs_lengths + _analytics->predict_rs_length_diff(); |
305 const size_t scanned_cards = _analytics->predict_card_num(adj_rs_lengths, /* gcs_are_young */ true); |
305 const size_t scanned_cards = _analytics->predict_card_num(adj_rs_lengths, true /* for_young_gc */); |
306 const double base_time_ms = |
306 const double base_time_ms = |
307 predict_base_elapsed_time_ms(pending_cards, scanned_cards) + |
307 predict_base_elapsed_time_ms(pending_cards, scanned_cards) + |
308 survivor_regions_evac_time; |
308 survivor_regions_evac_time; |
309 const uint available_free_regions = _free_regions_at_end_of_collection; |
309 const uint available_free_regions = _free_regions_at_end_of_collection; |
310 const uint base_free_regions = |
310 const uint base_free_regions = |
311 available_free_regions > _reserve_regions ? available_free_regions - _reserve_regions : 0; |
311 available_free_regions > _reserve_regions ? available_free_regions - _reserve_regions : 0; |
312 |
312 |
313 // Here, we will make sure that the shortest young length that |
313 // Here, we will make sure that the shortest young length that |
314 // makes sense fits within the target pause time. |
314 // makes sense fits within the target pause time. |
315 |
315 |
316 G1YoungLengthPredictor p(collector_state()->during_concurrent_mark(), |
316 G1YoungLengthPredictor p(collector_state()->mark_or_rebuild_in_progress(), |
317 base_time_ms, |
317 base_time_ms, |
318 base_free_regions, |
318 base_free_regions, |
319 target_pause_time_ms, |
319 target_pause_time_ms, |
320 this); |
320 this); |
321 if (p.will_fit(min_young_length)) { |
321 if (p.will_fit(min_young_length)) { |
382 const GrowableArray<HeapRegion*>* survivor_regions = _g1->survivor()->regions(); |
382 const GrowableArray<HeapRegion*>* survivor_regions = _g1->survivor()->regions(); |
383 |
383 |
384 for (GrowableArrayIterator<HeapRegion*> it = survivor_regions->begin(); |
384 for (GrowableArrayIterator<HeapRegion*> it = survivor_regions->begin(); |
385 it != survivor_regions->end(); |
385 it != survivor_regions->end(); |
386 ++it) { |
386 ++it) { |
387 survivor_regions_evac_time += predict_region_elapsed_time_ms(*it, collector_state()->gcs_are_young()); |
387 survivor_regions_evac_time += predict_region_elapsed_time_ms(*it, collector_state()->in_young_only_phase()); |
388 } |
388 } |
389 return survivor_regions_evac_time; |
389 return survivor_regions_evac_time; |
390 } |
390 } |
391 |
391 |
392 void G1Policy::revise_young_list_target_length_if_necessary(size_t rs_lengths) { |
392 void G1Policy::revise_young_list_target_length_if_necessary(size_t rs_lengths) { |
404 void G1Policy::update_rs_lengths_prediction() { |
404 void G1Policy::update_rs_lengths_prediction() { |
405 update_rs_lengths_prediction(_analytics->predict_rs_lengths()); |
405 update_rs_lengths_prediction(_analytics->predict_rs_lengths()); |
406 } |
406 } |
407 |
407 |
408 void G1Policy::update_rs_lengths_prediction(size_t prediction) { |
408 void G1Policy::update_rs_lengths_prediction(size_t prediction) { |
409 if (collector_state()->gcs_are_young() && adaptive_young_list_length()) { |
409 if (collector_state()->in_young_only_phase() && adaptive_young_list_length()) { |
410 _rs_lengths_prediction = prediction; |
410 _rs_lengths_prediction = prediction; |
411 } |
411 } |
412 } |
412 } |
413 |
413 |
414 void G1Policy::record_full_collection_start() { |
414 void G1Policy::record_full_collection_start() { |
415 _full_collection_start_sec = os::elapsedTime(); |
415 _full_collection_start_sec = os::elapsedTime(); |
416 // Release the future to-space so that it is available for compaction into. |
416 // Release the future to-space so that it is available for compaction into. |
417 collector_state()->set_full_collection(true); |
417 collector_state()->set_in_young_only_phase(false); |
|
418 collector_state()->set_in_full_gc(true); |
418 cset_chooser()->clear(); |
419 cset_chooser()->clear(); |
419 } |
420 } |
420 |
421 |
421 void G1Policy::record_full_collection_end() { |
422 void G1Policy::record_full_collection_end() { |
422 // Consider this like a collection pause for the purposes of allocation |
423 // Consider this like a collection pause for the purposes of allocation |
425 double full_gc_time_sec = end_sec - _full_collection_start_sec; |
426 double full_gc_time_sec = end_sec - _full_collection_start_sec; |
426 double full_gc_time_ms = full_gc_time_sec * 1000.0; |
427 double full_gc_time_ms = full_gc_time_sec * 1000.0; |
427 |
428 |
428 _analytics->update_recent_gc_times(end_sec, full_gc_time_ms); |
429 _analytics->update_recent_gc_times(end_sec, full_gc_time_ms); |
429 |
430 |
430 collector_state()->set_full_collection(false); |
431 collector_state()->set_in_full_gc(false); |
431 |
432 |
432 // "Nuke" the heuristics that control the young/mixed GC |
433 // "Nuke" the heuristics that control the young/mixed GC |
433 // transitions and make sure we start with young GCs after the Full GC. |
434 // transitions and make sure we start with young GCs after the Full GC. |
434 collector_state()->set_gcs_are_young(true); |
435 collector_state()->set_in_young_only_phase(true); |
435 collector_state()->set_last_young_gc(false); |
436 collector_state()->set_in_young_gc_before_mixed(false); |
436 collector_state()->set_initiate_conc_mark_if_possible(need_to_start_conc_mark("end of Full GC", 0)); |
437 collector_state()->set_initiate_conc_mark_if_possible(need_to_start_conc_mark("end of Full GC", 0)); |
437 collector_state()->set_during_initial_mark_pause(false); |
438 collector_state()->set_in_initial_mark_gc(false); |
438 collector_state()->set_in_marking_window(false); |
439 collector_state()->set_mark_or_rebuild_in_progress(false); |
439 collector_state()->set_in_marking_window_im(false); |
|
440 |
440 |
441 _short_lived_surv_rate_group->start_adding_regions(); |
441 _short_lived_surv_rate_group->start_adding_regions(); |
442 // also call this on any additional surv rate groups |
442 // also call this on any additional surv rate groups |
443 |
443 |
444 _free_regions_at_end_of_collection = _g1->num_free_regions(); |
444 _free_regions_at_end_of_collection = _g1->num_free_regions(); |
466 _pending_cards = _g1->pending_card_num(); |
466 _pending_cards = _g1->pending_card_num(); |
467 |
467 |
468 _collection_set->reset_bytes_used_before(); |
468 _collection_set->reset_bytes_used_before(); |
469 _bytes_copied_during_gc = 0; |
469 _bytes_copied_during_gc = 0; |
470 |
470 |
471 collector_state()->set_last_gc_was_young(false); |
|
472 |
|
473 // do that for any other surv rate groups |
471 // do that for any other surv rate groups |
474 _short_lived_surv_rate_group->stop_adding_regions(); |
472 _short_lived_surv_rate_group->stop_adding_regions(); |
475 _survivors_age_table.clear(); |
473 _survivors_age_table.clear(); |
476 |
474 |
477 assert(_g1->collection_set()->verify_young_ages(), "region age verification failed"); |
475 assert(_g1->collection_set()->verify_young_ages(), "region age verification failed"); |
478 } |
476 } |
479 |
477 |
480 void G1Policy::record_concurrent_mark_init_end(double mark_init_elapsed_time_ms) { |
478 void G1Policy::record_concurrent_mark_init_end(double mark_init_elapsed_time_ms) { |
481 collector_state()->set_during_marking(true); |
|
482 assert(!collector_state()->initiate_conc_mark_if_possible(), "we should have cleared it by now"); |
479 assert(!collector_state()->initiate_conc_mark_if_possible(), "we should have cleared it by now"); |
483 collector_state()->set_during_initial_mark_pause(false); |
480 collector_state()->set_in_initial_mark_gc(false); |
484 } |
481 } |
485 |
482 |
486 void G1Policy::record_concurrent_mark_remark_start() { |
483 void G1Policy::record_concurrent_mark_remark_start() { |
487 _mark_remark_start_sec = os::elapsedTime(); |
484 _mark_remark_start_sec = os::elapsedTime(); |
488 collector_state()->set_during_marking(false); |
|
489 } |
485 } |
490 |
486 |
491 void G1Policy::record_concurrent_mark_remark_end() { |
487 void G1Policy::record_concurrent_mark_remark_end() { |
492 double end_time_sec = os::elapsedTime(); |
488 double end_time_sec = os::elapsedTime(); |
493 double elapsed_time_ms = (end_time_sec - _mark_remark_start_sec)*1000.0; |
489 double elapsed_time_ms = (end_time_sec - _mark_remark_start_sec)*1000.0; |
526 CollectionSetChooser* G1Policy::cset_chooser() const { |
522 CollectionSetChooser* G1Policy::cset_chooser() const { |
527 return _collection_set->cset_chooser(); |
523 return _collection_set->cset_chooser(); |
528 } |
524 } |
529 |
525 |
530 bool G1Policy::about_to_start_mixed_phase() const { |
526 bool G1Policy::about_to_start_mixed_phase() const { |
531 return _g1->concurrent_mark()->cm_thread()->during_cycle() || collector_state()->last_young_gc(); |
527 return _g1->concurrent_mark()->cm_thread()->during_cycle() || collector_state()->in_young_gc_before_mixed(); |
532 } |
528 } |
533 |
529 |
534 bool G1Policy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) { |
530 bool G1Policy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) { |
535 if (about_to_start_mixed_phase()) { |
531 if (about_to_start_mixed_phase()) { |
536 return false; |
532 return false; |
542 size_t alloc_byte_size = alloc_word_size * HeapWordSize; |
538 size_t alloc_byte_size = alloc_word_size * HeapWordSize; |
543 size_t marking_request_bytes = cur_used_bytes + alloc_byte_size; |
539 size_t marking_request_bytes = cur_used_bytes + alloc_byte_size; |
544 |
540 |
545 bool result = false; |
541 bool result = false; |
546 if (marking_request_bytes > marking_initiating_used_threshold) { |
542 if (marking_request_bytes > marking_initiating_used_threshold) { |
547 result = collector_state()->gcs_are_young() && !collector_state()->last_young_gc(); |
543 result = collector_state()->in_young_only_phase() && !collector_state()->in_young_gc_before_mixed(); |
548 log_debug(gc, ergo, ihop)("%s occupancy: " SIZE_FORMAT "B allocation request: " SIZE_FORMAT "B threshold: " SIZE_FORMAT "B (%1.2f) source: %s", |
544 log_debug(gc, ergo, ihop)("%s occupancy: " SIZE_FORMAT "B allocation request: " SIZE_FORMAT "B threshold: " SIZE_FORMAT "B (%1.2f) source: %s", |
549 result ? "Request concurrent cycle initiation (occupancy higher than threshold)" : "Do not request concurrent cycle initiation (still doing mixed collections)", |
545 result ? "Request concurrent cycle initiation (occupancy higher than threshold)" : "Do not request concurrent cycle initiation (still doing mixed collections)", |
550 cur_used_bytes, alloc_byte_size, marking_initiating_used_threshold, (double) marking_initiating_used_threshold / _g1->capacity() * 100, source); |
546 cur_used_bytes, alloc_byte_size, marking_initiating_used_threshold, (double) marking_initiating_used_threshold / _g1->capacity() * 100, source); |
551 } |
547 } |
552 |
548 |
559 void G1Policy::record_collection_pause_end(double pause_time_ms, size_t cards_scanned, size_t heap_used_bytes_before_gc) { |
555 void G1Policy::record_collection_pause_end(double pause_time_ms, size_t cards_scanned, size_t heap_used_bytes_before_gc) { |
560 double end_time_sec = os::elapsedTime(); |
556 double end_time_sec = os::elapsedTime(); |
561 |
557 |
562 size_t cur_used_bytes = _g1->used(); |
558 size_t cur_used_bytes = _g1->used(); |
563 assert(cur_used_bytes == _g1->recalculate_used(), "It should!"); |
559 assert(cur_used_bytes == _g1->recalculate_used(), "It should!"); |
564 bool last_pause_included_initial_mark = false; |
560 bool this_pause_included_initial_mark = false; |
|
561 bool this_pause_was_young_only = collector_state()->in_young_only_phase(); |
|
562 |
565 bool update_stats = !_g1->evacuation_failed(); |
563 bool update_stats = !_g1->evacuation_failed(); |
566 |
564 |
567 record_pause(young_gc_pause_kind(), end_time_sec - pause_time_ms / 1000.0, end_time_sec); |
565 record_pause(young_gc_pause_kind(), end_time_sec - pause_time_ms / 1000.0, end_time_sec); |
568 |
566 |
569 _collection_pause_end_millis = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; |
567 _collection_pause_end_millis = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; |
570 |
568 |
571 last_pause_included_initial_mark = collector_state()->during_initial_mark_pause(); |
569 this_pause_included_initial_mark = collector_state()->in_initial_mark_gc(); |
572 if (last_pause_included_initial_mark) { |
570 if (this_pause_included_initial_mark) { |
573 record_concurrent_mark_init_end(0.0); |
571 record_concurrent_mark_init_end(0.0); |
574 } else { |
572 } else { |
575 maybe_start_marking(); |
573 maybe_start_marking(); |
576 } |
574 } |
577 |
575 |
600 (end_time_sec - _analytics->last_known_gc_end_time_sec()) * 1000.0; |
598 (end_time_sec - _analytics->last_known_gc_end_time_sec()) * 1000.0; |
601 _analytics->update_recent_gc_times(end_time_sec, pause_time_ms); |
599 _analytics->update_recent_gc_times(end_time_sec, pause_time_ms); |
602 _analytics->compute_pause_time_ratio(interval_ms, pause_time_ms); |
600 _analytics->compute_pause_time_ratio(interval_ms, pause_time_ms); |
603 } |
601 } |
604 |
602 |
605 bool new_in_marking_window = collector_state()->in_marking_window(); |
603 if (collector_state()->in_young_gc_before_mixed()) { |
606 bool new_in_marking_window_im = false; |
604 assert(!this_pause_included_initial_mark, "The young GC before mixed is not allowed to be an initial mark GC"); |
607 if (last_pause_included_initial_mark) { |
605 // This has been the young GC before we start doing mixed GCs. We already |
608 new_in_marking_window = true; |
|
609 new_in_marking_window_im = true; |
|
610 } |
|
611 |
|
612 if (collector_state()->last_young_gc()) { |
|
613 assert(!last_pause_included_initial_mark, "The last young GC is not allowed to be an initial mark GC"); |
|
614 // This has been the "last young GC" before we start doing mixed GCs. We already |
|
615 // decided to start mixed GCs much earlier, so there is nothing to do except |
606 // decided to start mixed GCs much earlier, so there is nothing to do except |
616 // advancing the state. |
607 // advancing the state. |
617 collector_state()->set_gcs_are_young(false); |
608 collector_state()->set_in_young_only_phase(false); |
618 collector_state()->set_last_young_gc(false); |
609 collector_state()->set_in_young_gc_before_mixed(false); |
619 } |
610 } else if (!this_pause_was_young_only) { |
620 |
|
621 if (!collector_state()->last_gc_was_young()) { |
|
622 // This is a mixed GC. Here we decide whether to continue doing more |
611 // This is a mixed GC. Here we decide whether to continue doing more |
623 // mixed GCs or not. |
612 // mixed GCs or not. |
624 if (!next_gc_should_be_mixed("continue mixed GCs", |
613 if (!next_gc_should_be_mixed("continue mixed GCs", |
625 "do not continue mixed GCs")) { |
614 "do not continue mixed GCs")) { |
626 collector_state()->set_gcs_are_young(true); |
615 collector_state()->set_in_young_only_phase(true); |
627 |
616 |
628 clear_collection_set_candidates(); |
617 clear_collection_set_candidates(); |
629 maybe_start_marking(); |
618 maybe_start_marking(); |
630 } |
619 } |
631 } |
620 } |
644 _analytics->report_cost_scan_hcc(scan_hcc_time_ms); |
633 _analytics->report_cost_scan_hcc(scan_hcc_time_ms); |
645 |
634 |
646 double cost_per_entry_ms = 0.0; |
635 double cost_per_entry_ms = 0.0; |
647 if (cards_scanned > 10) { |
636 if (cards_scanned > 10) { |
648 cost_per_entry_ms = average_time_ms(G1GCPhaseTimes::ScanRS) / (double) cards_scanned; |
637 cost_per_entry_ms = average_time_ms(G1GCPhaseTimes::ScanRS) / (double) cards_scanned; |
649 _analytics->report_cost_per_entry_ms(cost_per_entry_ms, collector_state()->last_gc_was_young()); |
638 _analytics->report_cost_per_entry_ms(cost_per_entry_ms, this_pause_was_young_only); |
650 } |
639 } |
651 |
640 |
652 if (_max_rs_lengths > 0) { |
641 if (_max_rs_lengths > 0) { |
653 double cards_per_entry_ratio = |
642 double cards_per_entry_ratio = |
654 (double) cards_scanned / (double) _max_rs_lengths; |
643 (double) cards_scanned / (double) _max_rs_lengths; |
655 _analytics->report_cards_per_entry_ratio(cards_per_entry_ratio, collector_state()->last_gc_was_young()); |
644 _analytics->report_cards_per_entry_ratio(cards_per_entry_ratio, this_pause_was_young_only); |
656 } |
645 } |
657 |
646 |
658 // This is defensive. For a while _max_rs_lengths could get |
647 // This is defensive. For a while _max_rs_lengths could get |
659 // smaller than _recorded_rs_lengths which was causing |
648 // smaller than _recorded_rs_lengths which was causing |
660 // rs_length_diff to get very large and mess up the RSet length |
649 // rs_length_diff to get very large and mess up the RSet length |
679 size_t copied_bytes = _collection_set->bytes_used_before() - freed_bytes; |
668 size_t copied_bytes = _collection_set->bytes_used_before() - freed_bytes; |
680 double cost_per_byte_ms = 0.0; |
669 double cost_per_byte_ms = 0.0; |
681 |
670 |
682 if (copied_bytes > 0) { |
671 if (copied_bytes > 0) { |
683 cost_per_byte_ms = average_time_ms(G1GCPhaseTimes::ObjCopy) / (double) copied_bytes; |
672 cost_per_byte_ms = average_time_ms(G1GCPhaseTimes::ObjCopy) / (double) copied_bytes; |
684 _analytics->report_cost_per_byte_ms(cost_per_byte_ms, collector_state()->in_marking_window()); |
673 _analytics->report_cost_per_byte_ms(cost_per_byte_ms, collector_state()->mark_or_rebuild_in_progress()); |
685 } |
674 } |
686 |
675 |
687 if (_collection_set->young_region_length() > 0) { |
676 if (_collection_set->young_region_length() > 0) { |
688 _analytics->report_young_other_cost_per_region_ms(young_other_time_ms() / |
677 _analytics->report_young_other_cost_per_region_ms(young_other_time_ms() / |
689 _collection_set->young_region_length()); |
678 _collection_set->young_region_length()); |
698 |
687 |
699 _analytics->report_pending_cards((double) _pending_cards); |
688 _analytics->report_pending_cards((double) _pending_cards); |
700 _analytics->report_rs_lengths((double) _max_rs_lengths); |
689 _analytics->report_rs_lengths((double) _max_rs_lengths); |
701 } |
690 } |
702 |
691 |
703 collector_state()->set_in_marking_window(new_in_marking_window); |
692 assert(!(this_pause_included_initial_mark && collector_state()->mark_or_rebuild_in_progress()), |
704 collector_state()->set_in_marking_window_im(new_in_marking_window_im); |
693 "If the last pause has been an initial mark, we should not have been in the marking window"); |
|
694 if (this_pause_included_initial_mark) { |
|
695 collector_state()->set_mark_or_rebuild_in_progress(true); |
|
696 } |
|
697 |
705 _free_regions_at_end_of_collection = _g1->num_free_regions(); |
698 _free_regions_at_end_of_collection = _g1->num_free_regions(); |
706 // IHOP control wants to know the expected young gen length if it were not |
699 // IHOP control wants to know the expected young gen length if it were not |
707 // restrained by the heap reserve. Using the actual length would make the |
700 // restrained by the heap reserve. Using the actual length would make the |
708 // prediction too small and the limit the young gen every time we get to the |
701 // prediction too small and the limit the young gen every time we get to the |
709 // predicted target occupancy. |
702 // predicted target occupancy. |
710 size_t last_unrestrained_young_length = update_young_list_max_and_target_length(); |
703 size_t last_unrestrained_young_length = update_young_list_max_and_target_length(); |
711 update_rs_lengths_prediction(); |
704 update_rs_lengths_prediction(); |
712 |
705 |
713 update_ihop_prediction(app_time_ms / 1000.0, |
706 update_ihop_prediction(app_time_ms / 1000.0, |
714 _bytes_allocated_in_old_since_last_gc, |
707 _bytes_allocated_in_old_since_last_gc, |
715 last_unrestrained_young_length * HeapRegion::GrainBytes); |
708 last_unrestrained_young_length * HeapRegion::GrainBytes, |
|
709 this_pause_was_young_only); |
716 _bytes_allocated_in_old_since_last_gc = 0; |
710 _bytes_allocated_in_old_since_last_gc = 0; |
717 |
711 |
718 _ihop_control->send_trace_event(_g1->gc_tracer_stw()); |
712 _ihop_control->send_trace_event(_g1->gc_tracer_stw()); |
719 |
713 |
720 // Note that _mmu_tracker->max_gc_time() returns the time in seconds. |
714 // Note that _mmu_tracker->max_gc_time() returns the time in seconds. |
728 update_rs_time_goal_ms = 0; |
722 update_rs_time_goal_ms = 0; |
729 } else { |
723 } else { |
730 update_rs_time_goal_ms -= scan_hcc_time_ms; |
724 update_rs_time_goal_ms -= scan_hcc_time_ms; |
731 } |
725 } |
732 _g1->concurrent_refine()->adjust(average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms, |
726 _g1->concurrent_refine()->adjust(average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms, |
733 phase_times()->sum_thread_work_items(G1GCPhaseTimes::UpdateRS), |
727 phase_times()->sum_thread_work_items(G1GCPhaseTimes::UpdateRS), |
734 update_rs_time_goal_ms); |
728 update_rs_time_goal_ms); |
735 |
729 |
736 cset_chooser()->verify(); |
730 cset_chooser()->verify(); |
737 } |
731 } |
738 |
732 |
739 G1IHOPControl* G1Policy::create_ihop_control(const G1Predictions* predictor){ |
733 G1IHOPControl* G1Policy::create_ihop_control(const G1Predictions* predictor){ |
747 } |
741 } |
748 } |
742 } |
749 |
743 |
750 void G1Policy::update_ihop_prediction(double mutator_time_s, |
744 void G1Policy::update_ihop_prediction(double mutator_time_s, |
751 size_t mutator_alloc_bytes, |
745 size_t mutator_alloc_bytes, |
752 size_t young_gen_size) { |
746 size_t young_gen_size, |
|
747 bool this_gc_was_young_only) { |
753 // Always try to update IHOP prediction. Even evacuation failures give information |
748 // Always try to update IHOP prediction. Even evacuation failures give information |
754 // about e.g. whether to start IHOP earlier next time. |
749 // about e.g. whether to start IHOP earlier next time. |
755 |
750 |
756 // Avoid using really small application times that might create samples with |
751 // Avoid using really small application times that might create samples with |
757 // very high or very low values. They may be caused by e.g. back-to-back gcs. |
752 // very high or very low values. They may be caused by e.g. back-to-back gcs. |
758 double const min_valid_time = 1e-6; |
753 double const min_valid_time = 1e-6; |
759 |
754 |
760 bool report = false; |
755 bool report = false; |
761 |
756 |
762 double marking_to_mixed_time = -1.0; |
757 double marking_to_mixed_time = -1.0; |
763 if (!collector_state()->last_gc_was_young() && _initial_mark_to_mixed.has_result()) { |
758 if (!this_gc_was_young_only && _initial_mark_to_mixed.has_result()) { |
764 marking_to_mixed_time = _initial_mark_to_mixed.last_marking_time(); |
759 marking_to_mixed_time = _initial_mark_to_mixed.last_marking_time(); |
765 assert(marking_to_mixed_time > 0.0, |
760 assert(marking_to_mixed_time > 0.0, |
766 "Initial mark to mixed time must be larger than zero but is %.3f", |
761 "Initial mark to mixed time must be larger than zero but is %.3f", |
767 marking_to_mixed_time); |
762 marking_to_mixed_time); |
768 if (marking_to_mixed_time > min_valid_time) { |
763 if (marking_to_mixed_time > min_valid_time) { |
773 |
768 |
774 // As an approximation for the young gc promotion rates during marking we use |
769 // As an approximation for the young gc promotion rates during marking we use |
775 // all of them. In many applications there are only a few if any young gcs during |
770 // all of them. In many applications there are only a few if any young gcs during |
776 // marking, which makes any prediction useless. This increases the accuracy of the |
771 // marking, which makes any prediction useless. This increases the accuracy of the |
777 // prediction. |
772 // prediction. |
778 if (collector_state()->last_gc_was_young() && mutator_time_s > min_valid_time) { |
773 if (this_gc_was_young_only && mutator_time_s > min_valid_time) { |
779 _ihop_control->update_allocation_info(mutator_time_s, mutator_alloc_bytes, young_gen_size); |
774 _ihop_control->update_allocation_info(mutator_time_s, mutator_alloc_bytes, young_gen_size); |
780 report = true; |
775 report = true; |
781 } |
776 } |
782 |
777 |
783 if (report) { |
778 if (report) { |
809 |
804 |
810 double G1Policy::predict_base_elapsed_time_ms(size_t pending_cards, |
805 double G1Policy::predict_base_elapsed_time_ms(size_t pending_cards, |
811 size_t scanned_cards) const { |
806 size_t scanned_cards) const { |
812 return |
807 return |
813 _analytics->predict_rs_update_time_ms(pending_cards) + |
808 _analytics->predict_rs_update_time_ms(pending_cards) + |
814 _analytics->predict_rs_scan_time_ms(scanned_cards, collector_state()->gcs_are_young()) + |
809 _analytics->predict_rs_scan_time_ms(scanned_cards, collector_state()->in_young_only_phase()) + |
815 _analytics->predict_constant_other_time_ms(); |
810 _analytics->predict_constant_other_time_ms(); |
816 } |
811 } |
817 |
812 |
818 double G1Policy::predict_base_elapsed_time_ms(size_t pending_cards) const { |
813 double G1Policy::predict_base_elapsed_time_ms(size_t pending_cards) const { |
819 size_t rs_length = _analytics->predict_rs_lengths() + _analytics->predict_rs_length_diff(); |
814 size_t rs_length = _analytics->predict_rs_lengths() + _analytics->predict_rs_length_diff(); |
820 size_t card_num = _analytics->predict_card_num(rs_length, collector_state()->gcs_are_young()); |
815 size_t card_num = _analytics->predict_card_num(rs_length, collector_state()->in_young_only_phase()); |
821 return predict_base_elapsed_time_ms(pending_cards, card_num); |
816 return predict_base_elapsed_time_ms(pending_cards, card_num); |
822 } |
817 } |
823 |
818 |
824 size_t G1Policy::predict_bytes_to_copy(HeapRegion* hr) const { |
819 size_t G1Policy::predict_bytes_to_copy(HeapRegion* hr) const { |
825 size_t bytes_to_copy; |
820 size_t bytes_to_copy; |
841 // we're predicting for. |
836 // we're predicting for. |
842 size_t card_num = _analytics->predict_card_num(rs_length, for_young_gc); |
837 size_t card_num = _analytics->predict_card_num(rs_length, for_young_gc); |
843 size_t bytes_to_copy = predict_bytes_to_copy(hr); |
838 size_t bytes_to_copy = predict_bytes_to_copy(hr); |
844 |
839 |
845 double region_elapsed_time_ms = |
840 double region_elapsed_time_ms = |
846 _analytics->predict_rs_scan_time_ms(card_num, collector_state()->gcs_are_young()) + |
841 _analytics->predict_rs_scan_time_ms(card_num, collector_state()->in_young_only_phase()) + |
847 _analytics->predict_object_copy_time_ms(bytes_to_copy, collector_state()->during_concurrent_mark()); |
842 _analytics->predict_object_copy_time_ms(bytes_to_copy, collector_state()->mark_or_rebuild_in_progress()); |
848 |
843 |
849 // The prediction of the "other" time for this region is based |
844 // The prediction of the "other" time for this region is based |
850 // upon the region type and NOT the GC type. |
845 // upon the region type and NOT the GC type. |
851 if (hr->is_young()) { |
846 if (hr->is_young()) { |
852 region_elapsed_time_ms += _analytics->predict_young_other_time_ms(1); |
847 region_elapsed_time_ms += _analytics->predict_young_other_time_ms(1); |
925 return false; |
920 return false; |
926 } |
921 } |
927 } |
922 } |
928 |
923 |
929 void G1Policy::initiate_conc_mark() { |
924 void G1Policy::initiate_conc_mark() { |
930 collector_state()->set_during_initial_mark_pause(true); |
925 collector_state()->set_in_initial_mark_gc(true); |
931 collector_state()->set_initiate_conc_mark_if_possible(false); |
926 collector_state()->set_initiate_conc_mark_if_possible(false); |
932 } |
927 } |
933 |
928 |
934 void G1Policy::decide_on_conc_mark_initiation() { |
929 void G1Policy::decide_on_conc_mark_initiation() { |
935 // We are about to decide on whether this pause will be an |
930 // We are about to decide on whether this pause will be an |
936 // initial-mark pause. |
931 // initial-mark pause. |
937 |
932 |
938 // First, collector_state()->during_initial_mark_pause() should not be already set. We |
933 // First, collector_state()->in_initial_mark_gc() should not be already set. We |
939 // will set it here if we have to. However, it should be cleared by |
934 // will set it here if we have to. However, it should be cleared by |
940 // the end of the pause (it's only set for the duration of an |
935 // the end of the pause (it's only set for the duration of an |
941 // initial-mark pause). |
936 // initial-mark pause). |
942 assert(!collector_state()->during_initial_mark_pause(), "pre-condition"); |
937 assert(!collector_state()->in_initial_mark_gc(), "pre-condition"); |
943 |
938 |
944 if (collector_state()->initiate_conc_mark_if_possible()) { |
939 if (collector_state()->initiate_conc_mark_if_possible()) { |
945 // We had noticed on a previous pause that the heap occupancy has |
940 // We had noticed on a previous pause that the heap occupancy has |
946 // gone over the initiating threshold and we should start a |
941 // gone over the initiating threshold and we should start a |
947 // concurrent marking cycle. So we might initiate one. |
942 // concurrent marking cycle. So we might initiate one. |
948 |
943 |
949 if (!about_to_start_mixed_phase() && collector_state()->gcs_are_young()) { |
944 if (!about_to_start_mixed_phase() && collector_state()->in_young_only_phase()) { |
950 // Initiate a new initial mark if there is no marking or reclamation going on. |
945 // Initiate a new initial mark if there is no marking or reclamation going on. |
951 initiate_conc_mark(); |
946 initiate_conc_mark(); |
952 log_debug(gc, ergo)("Initiate concurrent cycle (concurrent cycle initiation requested)"); |
947 log_debug(gc, ergo)("Initiate concurrent cycle (concurrent cycle initiation requested)"); |
953 } else if (_g1->is_user_requested_concurrent_full_gc(_g1->gc_cause())) { |
948 } else if (_g1->is_user_requested_concurrent_full_gc(_g1->gc_cause())) { |
954 // Initiate a user requested initial mark. An initial mark must be young only |
949 // Initiate a user requested initial mark. An initial mark must be young only |
955 // GC, so the collector state must be updated to reflect this. |
950 // GC, so the collector state must be updated to reflect this. |
956 collector_state()->set_gcs_are_young(true); |
951 collector_state()->set_in_young_only_phase(true); |
957 collector_state()->set_last_young_gc(false); |
952 collector_state()->set_in_young_gc_before_mixed(false); |
958 |
953 |
959 // We might have ended up coming here about to start a mixed phase with a collection set |
954 // We might have ended up coming here about to start a mixed phase with a collection set |
960 // active. The following remark might change the change the "evacuation efficiency" of |
955 // active. The following remark might change the change the "evacuation efficiency" of |
961 // the regions in this set, leading to failing asserts later. |
956 // the regions in this set, leading to failing asserts later. |
962 // Since the concurrent cycle will recreate the collection set anyway, simply drop it here. |
957 // Since the concurrent cycle will recreate the collection set anyway, simply drop it here. |
988 bool mixed_gc_pending = next_gc_should_be_mixed("request mixed gcs", "request young-only gcs"); |
983 bool mixed_gc_pending = next_gc_should_be_mixed("request mixed gcs", "request young-only gcs"); |
989 if (!mixed_gc_pending) { |
984 if (!mixed_gc_pending) { |
990 clear_collection_set_candidates(); |
985 clear_collection_set_candidates(); |
991 abort_time_to_mixed_tracking(); |
986 abort_time_to_mixed_tracking(); |
992 } |
987 } |
993 collector_state()->set_last_young_gc(mixed_gc_pending); |
988 collector_state()->set_in_young_gc_before_mixed(mixed_gc_pending); |
994 collector_state()->set_in_marking_window(false); |
989 collector_state()->set_mark_or_rebuild_in_progress(false); |
995 |
990 |
996 double end_sec = os::elapsedTime(); |
991 double end_sec = os::elapsedTime(); |
997 double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0; |
992 double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0; |
998 _analytics->report_concurrent_mark_cleanup_times_ms(elapsed_time_ms); |
993 _analytics->report_concurrent_mark_cleanup_times_ms(elapsed_time_ms); |
999 _analytics->append_prev_collection_pause_end_ms(elapsed_time_ms); |
994 _analytics->append_prev_collection_pause_end_ms(elapsed_time_ms); |
1028 collector_state()->set_initiate_conc_mark_if_possible(true); |
1023 collector_state()->set_initiate_conc_mark_if_possible(true); |
1029 } |
1024 } |
1030 } |
1025 } |
1031 |
1026 |
1032 G1Policy::PauseKind G1Policy::young_gc_pause_kind() const { |
1027 G1Policy::PauseKind G1Policy::young_gc_pause_kind() const { |
1033 assert(!collector_state()->full_collection(), "must be"); |
1028 assert(!collector_state()->in_full_gc(), "must be"); |
1034 if (collector_state()->during_initial_mark_pause()) { |
1029 if (collector_state()->in_initial_mark_gc()) { |
1035 assert(collector_state()->last_gc_was_young(), "must be"); |
1030 assert(!collector_state()->in_young_gc_before_mixed(), "must be"); |
1036 assert(!collector_state()->last_young_gc(), "must be"); |
|
1037 return InitialMarkGC; |
1031 return InitialMarkGC; |
1038 } else if (collector_state()->last_young_gc()) { |
1032 } else if (collector_state()->in_young_gc_before_mixed()) { |
1039 assert(!collector_state()->during_initial_mark_pause(), "must be"); |
1033 assert(!collector_state()->in_initial_mark_gc(), "must be"); |
1040 assert(collector_state()->last_gc_was_young(), "must be"); |
|
1041 return LastYoungGC; |
1034 return LastYoungGC; |
1042 } else if (!collector_state()->last_gc_was_young()) { |
1035 } else if (collector_state()->in_mixed_phase()) { |
1043 assert(!collector_state()->during_initial_mark_pause(), "must be"); |
1036 assert(!collector_state()->in_initial_mark_gc(), "must be"); |
1044 assert(!collector_state()->last_young_gc(), "must be"); |
1037 assert(!collector_state()->in_young_gc_before_mixed(), "must be"); |
1045 return MixedGC; |
1038 return MixedGC; |
1046 } else { |
1039 } else { |
1047 assert(collector_state()->last_gc_was_young(), "must be"); |
1040 assert(!collector_state()->in_initial_mark_gc(), "must be"); |
1048 assert(!collector_state()->during_initial_mark_pause(), "must be"); |
1041 assert(!collector_state()->in_young_gc_before_mixed(), "must be"); |
1049 assert(!collector_state()->last_young_gc(), "must be"); |
|
1050 return YoungOnlyGC; |
1042 return YoungOnlyGC; |
1051 } |
1043 } |
1052 } |
1044 } |
1053 |
1045 |
1054 void G1Policy::record_pause(PauseKind kind, double start, double end) { |
1046 void G1Policy::record_pause(PauseKind kind, double start, double end) { |