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);
}