--- old/src/hotspot/share/gc/g1/g1Policy.cpp 2020-02-19 11:43:18.797786770 +0100 +++ new/src/hotspot/share/gc/g1/g1Policy.cpp 2020-02-19 11:43:18.391774085 +0100 @@ -32,6 +32,7 @@ #include "gc/g1/g1ConcurrentMarkThread.inline.hpp" #include "gc/g1/g1ConcurrentRefine.hpp" #include "gc/g1/g1CollectionSetChooser.hpp" +#include "gc/g1/g1HeapSizingPolicy.hpp" #include "gc/g1/g1HeterogeneousHeapPolicy.hpp" #include "gc/g1/g1HotCardCache.hpp" #include "gc/g1/g1IHOPControl.hpp" @@ -76,6 +77,7 @@ _total_concurrent_refined_cards(0), _total_concurrent_refinement_time(), _bytes_allocated_in_old_since_last_gc(0), + _minimum_desired_bytes_after_last_cm(0), _initial_mark_to_mixed(), _collection_set(NULL), _g1h(NULL), @@ -1095,6 +1097,21 @@ } } +void G1Policy::determine_desired_bytes_after_concurrent_mark() { + size_t cur_used_bytes = _g1h->non_young_capacity_bytes(); + + size_t overall_target_capacity = _g1h->heap_sizing_policy()->target_heap_capacity(cur_used_bytes, MinHeapFreeRatio); + + size_t desired_bytes_after_concurrent_mark = _g1h->policy()->desired_bytes_after_concurrent_mark(cur_used_bytes); + + _minimum_desired_bytes_after_last_cm = MIN2(desired_bytes_after_concurrent_mark, overall_target_capacity); + + log_debug(gc, ergo, heap)("Expansion amount after remark used: " SIZE_FORMAT " " + "minimum_desired_capacity " SIZE_FORMAT " desired_bytes_after_concurrent_mark: " SIZE_FORMAT " " + "minimum_desired_bytes_after_concurrent_mark " SIZE_FORMAT, + cur_used_bytes, overall_target_capacity, desired_bytes_after_concurrent_mark, _minimum_desired_bytes_after_last_cm); +} + void G1Policy::record_concurrent_mark_cleanup_end() { G1CollectionSetCandidates* candidates = G1CollectionSetChooser::build(_g1h->workers(), _g1h->num_regions()); _collection_set->set_candidates(candidates); @@ -1107,6 +1124,8 @@ collector_state()->set_in_young_gc_before_mixed(mixed_gc_pending); collector_state()->set_mark_or_rebuild_in_progress(false); + determine_desired_bytes_after_concurrent_mark(); + double end_sec = os::elapsedTime(); double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0; _analytics->report_concurrent_mark_cleanup_times_ms(elapsed_time_ms); @@ -1199,8 +1218,10 @@ const char* false_action_str) const { G1CollectionSetCandidates* candidates = _collection_set->candidates(); - if (candidates->is_empty()) { - log_debug(gc, ergo)("%s (candidate old regions not available)", false_action_str); + if (candidates == NULL || candidates->is_empty()) { + if (false_action_str != NULL) { + log_debug(gc, ergo)("%s (candidate old regions not available)", false_action_str); + } return false; } @@ -1209,12 +1230,16 @@ double reclaimable_percent = reclaimable_bytes_percent(reclaimable_bytes); double threshold = (double) G1HeapWastePercent; if (reclaimable_percent <= threshold) { - log_debug(gc, ergo)("%s (reclaimable percentage not over threshold). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT, - false_action_str, candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, G1HeapWastePercent); + if (false_action_str != NULL) { + log_debug(gc, ergo)("%s (reclaimable percentage not over threshold). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT, + false_action_str, candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, G1HeapWastePercent); + } return false; } - log_debug(gc, ergo)("%s (candidate old regions available). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT, - true_action_str, candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, G1HeapWastePercent); + if (true_action_str != NULL) { + log_debug(gc, ergo)("%s (candidate old regions available). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT, + true_action_str, candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, G1HeapWastePercent); + } return true; } @@ -1411,3 +1436,10 @@ // the survivor regions from this evacuation pause as 'young' // at the start of the next. } + +size_t G1Policy::desired_bytes_after_concurrent_mark(size_t used_bytes) { + size_t minimum_desired_buffer_size = _ihop_control->predict_unrestrained_buffer_size(); + return minimum_desired_buffer_size != 0 ? + minimum_desired_buffer_size : + _young_list_max_length * HeapRegion::GrainBytes + _reserve_regions * HeapRegion::GrainBytes + used_bytes; +}