--- old/src/hotspot/share/gc/g1/g1CollectedHeap.cpp 2020-02-19 11:43:05.130359789 +0100 +++ new/src/hotspot/share/gc/g1/g1CollectedHeap.cpp 2020-02-19 11:43:04.710346667 +0100 @@ -1061,7 +1061,8 @@ assert(num_free_regions() == 0, "we should not have added any free regions"); rebuild_region_sets(false /* free_list_only */); abort_refinement(); - resize_heap_if_necessary(); + + resize_heap_after_full_gc(); // Rebuild the strong code root lists for each region rebuild_strong_code_roots(); @@ -1165,41 +1166,17 @@ clear_all_soft_refs); } -void G1CollectedHeap::resize_heap_if_necessary() { +void G1CollectedHeap::resize_heap_after_full_gc() { assert_at_safepoint_on_vm_thread(); + assert(collector_state()->in_full_gc(), "Must be"); // Capacity, free and used after the GC counted as full regions to // include the waste in the following calculations. const size_t capacity_after_gc = capacity(); const size_t used_after_gc = capacity_after_gc - unused_committed_regions_in_bytes(); - // This is enforced in arguments.cpp. - assert(MinHeapFreeRatio <= MaxHeapFreeRatio, - "otherwise the code below doesn't make sense"); - - // We don't have floating point command-line arguments - const double minimum_free_percentage = (double) MinHeapFreeRatio / 100.0; - const double maximum_used_percentage = 1.0 - minimum_free_percentage; - const double maximum_free_percentage = (double) MaxHeapFreeRatio / 100.0; - const double minimum_used_percentage = 1.0 - maximum_free_percentage; - - // We have to be careful here as these two calculations can overflow - // 32-bit size_t's. - double used_after_gc_d = (double) used_after_gc; - double minimum_desired_capacity_d = used_after_gc_d / maximum_used_percentage; - double maximum_desired_capacity_d = used_after_gc_d / minimum_used_percentage; - - // Let's make sure that they are both under the max heap size, which - // by default will make them fit into a size_t. - double desired_capacity_upper_bound = (double) MaxHeapSize; - minimum_desired_capacity_d = MIN2(minimum_desired_capacity_d, - desired_capacity_upper_bound); - maximum_desired_capacity_d = MIN2(maximum_desired_capacity_d, - desired_capacity_upper_bound); - - // We can now safely turn them into size_t's. - size_t minimum_desired_capacity = (size_t) minimum_desired_capacity_d; - size_t maximum_desired_capacity = (size_t) maximum_desired_capacity_d; + size_t minimum_desired_capacity = _heap_sizing_policy->target_heap_capacity(used_after_gc, MinHeapFreeRatio); + size_t maximum_desired_capacity = _heap_sizing_policy->target_heap_capacity(used_after_gc, MaxHeapFreeRatio); // This assert only makes sense here, before we adjust them // with respect to the min and max heap size. @@ -2424,6 +2401,10 @@ return _hrm->max_length() * HeapRegion::GrainBytes; } +size_t G1CollectedHeap::soft_max_capacity() const { + return clamp(align_up(SoftMaxHeapSize, HeapAlignment), MinHeapSize, max_capacity()); +} + jlong G1CollectedHeap::millis_since_last_gc() { // See the notes in GenCollectedHeap::millis_since_last_gc() // for more information about the implementation. @@ -2948,16 +2929,34 @@ verify_numa_regions("GC End"); } -void G1CollectedHeap::expand_heap_after_young_collection(){ - size_t expand_bytes = _heap_sizing_policy->expansion_amount(); +void G1CollectedHeap::resize_heap_after_young_collection() { + Ticks start = Ticks::now(); + if (!expand_heap_after_young_collection()) { + // If we don't attempt to expand heap, try if we need to shrink the heap + shrink_heap_after_young_collection(); + } + phase_times()->record_resize_heap_time((Ticks::now() - start).seconds() * 1000.0); +} + +bool G1CollectedHeap::expand_heap_after_young_collection(){ + size_t expand_bytes = _heap_sizing_policy->expansion_amount_after_young_collection(); if (expand_bytes > 0) { - // No need for an ergo logging here, - // expansion_amount() does this when it returns a value > 0. - double expand_ms; - if (!expand(expand_bytes, _workers, &expand_ms)) { + if (expand(expand_bytes, _workers, NULL)) { // We failed to expand the heap. Cannot do anything about it. } - phase_times()->record_expand_heap_time(expand_ms); + return true; + } + return false; +} + +void G1CollectedHeap::shrink_heap_after_young_collection() { + if (collector_state()->in_young_only_phase() || policy()->next_gc_should_be_mixed()) { + // Do the shrink during gc only at the end of mixed gc phase + return; + } + size_t shrink_bytes = _heap_sizing_policy->shrink_amount_at_last_mixed_gc(policy()->desired_bytes_after_concurrent_mark()); + if (shrink_bytes > 0) { + shrink(shrink_bytes); } } @@ -3126,7 +3125,7 @@ _allocator->init_mutator_alloc_regions(); - expand_heap_after_young_collection(); + resize_heap_after_young_collection(); double sample_end_time_sec = os::elapsedTime(); double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS;