Print this page
G1: Use SoftMaxHeapSize to guide GC heuristics

*** 1177,1209 **** // 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; // This assert only makes sense here, before we adjust them // with respect to the min and max heap size. assert(minimum_desired_capacity <= maximum_desired_capacity, "minimum_desired_capacity = " SIZE_FORMAT ", " --- 1177,1188 ---- // This is enforced in arguments.cpp. assert(MinHeapFreeRatio <= MaxHeapFreeRatio, "otherwise the code below doesn't make sense"); ! 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, MinHeapFreeRatio); // This assert only makes sense here, before we adjust them // with respect to the min and max heap size. assert(minimum_desired_capacity <= maximum_desired_capacity, "minimum_desired_capacity = " SIZE_FORMAT ", "
*** 2424,2433 **** --- 2403,2416 ---- size_t G1CollectedHeap::max_reserved_capacity() const { 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. jlong ret_val = (os::javaTimeNanos() / NANOSECS_PER_MILLISEC) - _policy->collection_pause_end_millis();
*** 2950,2969 **** _verifier->verify_after_gc(type); _verifier->check_bitmaps("GC End"); verify_numa_regions("GC End"); } ! void G1CollectedHeap::expand_heap_after_young_collection(){ ! size_t expand_bytes = _heap_sizing_policy->expansion_amount(); 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)) { // We failed to expand the heap. Cannot do anything about it. } ! phase_times()->record_expand_heap_time(expand_ms); } } const char* G1CollectedHeap::young_gc_name() const { if (collector_state()->in_initial_mark_gc()) { --- 2933,2977 ---- _verifier->verify_after_gc(type); _verifier->check_bitmaps("GC End"); verify_numa_regions("GC End"); } ! 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) { ! if (expand(expand_bytes, _workers, NULL)) { // We failed to expand the heap. Cannot do anything about it. } ! return true; ! } ! return false; ! } ! ! void G1CollectedHeap::shrink_heap_after_young_collection() { ! if (!collector_state()->finish_of_mixed_gc()) { ! // Do the shrink only after finish of mixed gc ! return; ! } ! size_t shrink_bytes = _heap_sizing_policy->shrink_amount_after_mixed_collections(); ! if (shrink_bytes > 0) { ! shrink(shrink_bytes); ! } ! } ! ! void G1CollectedHeap::expand_heap_after_concurrent_mark() { ! size_t expand_bytes = _heap_sizing_policy->expansion_amount_after_concurrent_mark(); ! if (expand_bytes > 0) { ! expand(expand_bytes, _workers, NULL); } } const char* G1CollectedHeap::young_gc_name() const { if (collector_state()->in_initial_mark_gc()) {
*** 3115,3125 **** allocate_dummy_regions(); _allocator->init_mutator_alloc_regions(); ! expand_heap_after_young_collection(); double sample_end_time_sec = os::elapsedTime(); double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS; policy()->record_collection_pause_end(pause_time_ms); } --- 3123,3133 ---- allocate_dummy_regions(); _allocator->init_mutator_alloc_regions(); ! 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; policy()->record_collection_pause_end(pause_time_ms); }