Print this page
G1: Use SoftMaxHeapSize to guide GC heuristics

@@ -1177,33 +1177,12 @@
 
   // 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, 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,10 +2403,14 @@
 
 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,20 +2933,45 @@
   _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();
+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()->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,11 +3123,11 @@
 
         allocate_dummy_regions();
 
         _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;
         policy()->record_collection_pause_end(pause_time_ms);
       }