src/hotspot/share/gc/z/zDirector.cpp
changeset 55002 da9840e2f7da
parent 50979 270b11dadbaf
child 55282 07ff89762205
child 58678 9cf78a70fa4f
--- a/src/hotspot/share/gc/z/zDirector.cpp	Wed May 22 21:49:31 2019 -0700
+++ b/src/hotspot/share/gc/z/zDirector.cpp	Thu May 23 08:09:29 2019 +0200
@@ -181,6 +181,25 @@
   return time_until_gc <= 0;
 }
 
+bool ZDirector::rule_high_usage() const {
+  // Perform GC if the amount of free memory is 5% or less. This is a preventive
+  // meassure in the case where the application has a very low allocation rate,
+  // such that the allocation rate rule doesn't trigger, but the amount of free
+  // memory is still slowly but surely heading towards zero. In this situation,
+  // we start a GC cycle to avoid a potential allocation stall later.
+
+  // Calculate amount of free memory available to Java threads. Note that
+  // the heap reserve is not available to Java threads and is therefore not
+  // considered part of the free memory.
+  const size_t max_capacity = ZHeap::heap()->current_max_capacity();
+  const size_t max_reserve = ZHeap::heap()->max_reserve();
+  const size_t used = ZHeap::heap()->used();
+  const size_t free_with_reserve = max_capacity - used;
+  const size_t free = free_with_reserve - MIN2(free_with_reserve, max_reserve);
+
+  return percent_of(free, max_capacity) <= 5.0;
+}
+
 GCCause::Cause ZDirector::make_gc_decision() const {
   // Rule 0: Timer
   if (rule_timer()) {
@@ -202,6 +221,11 @@
     return GCCause::_z_proactive;
   }
 
+  // Rule 4: High usage
+  if (rule_high_usage()) {
+    return GCCause::_z_high_usage;
+  }
+
   // No GC
   return GCCause::_no_gc;
 }