src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp

Print this page

        

@@ -957,5 +957,88 @@
     old_gen()->object_space()->mangle_unused_area();
     perm_gen()->object_space()->mangle_unused_area();
   }
 }
 #endif
+
+bool ParallelScavengeHeap::resize_by_free_ratio(bool isFullGC) {
+  if (MinHeapFreeRatio <= 0 && MaxHeapFreeRatio >= 100) {
+    // nothing to do in this case
+    return false;
+  }
+
+  PSOldGen* old = old_gen();
+  PSYoungGen* young = young_gen();
+
+  size_t capacity = old->capacity_in_bytes() + young->capacity_in_bytes();
+  size_t used = old->used_in_bytes() + young->used_in_bytes();
+  size_t init_size = old->init_gen_size() + young->init_gen_size();
+  size_t max_size = old->max_gen_size() + young->max_size();
+
+  // Shrink
+  if (MaxHeapFreeRatio < 100) {
+    const double maximum_free_percentage = MaxHeapFreeRatio / 100.0;
+    const double minimum_used_percentage = 1.0 - maximum_free_percentage;
+    const double max_tmp = used / minimum_used_percentage;
+    size_t maximum_desired_capacity = MIN2((size_t) max_tmp, max_size);
+    maximum_desired_capacity = MAX2(maximum_desired_capacity, init_size);
+
+    if (PrintGC && Verbose) {
+      const double free_ratio = 1.0 - (double) used / capacity;
+      gclog_or_tty->print("Shrink by free ratio: ");
+      gclog_or_tty->print("capacity : " SIZE_FORMAT ", ", capacity);
+      gclog_or_tty->print("used : " SIZE_FORMAT ", ", used);
+      gclog_or_tty->print_cr("free ratio : %f.2", free_ratio);
+    }
+
+    size_t free_bytes = capacity - used;
+    if (capacity > maximum_desired_capacity && free_bytes > 0) {
+      size_t young_gen_free_bytes = young->capacity_in_bytes() - young->used_in_bytes();
+      size_t old_gen_free_bytes = old->capacity_in_bytes() - old->used_in_bytes();
+      size_t shrink_bytes = capacity - maximum_desired_capacity;
+      if (isFullGC) {
+        size_t old_gen_shrink_bytes =
+            (size_t) (shrink_bytes * ((double) old_gen_free_bytes / free_bytes));
+        old->try_to_shrink_by(old_gen_shrink_bytes);
+      }
+      size_t young_gen_shrink_bytes =
+          (size_t) (shrink_bytes * ((double) young_gen_free_bytes / free_bytes));
+      young->try_to_shrink_by(young_gen_shrink_bytes);
+      return true;
+    }
+  }
+
+  // Expand
+  if (MinHeapFreeRatio > 0) {
+    const double minimum_free_percentage = MinHeapFreeRatio / 100.0;
+    const double maximum_used_percentage = 1.0 - minimum_free_percentage;
+    const double min_tmp = used / maximum_used_percentage;
+    size_t minimum_desired_capacity = MIN2((size_t) min_tmp, max_size);
+    minimum_desired_capacity = MAX2(minimum_desired_capacity, init_size);
+
+    if (PrintGC && Verbose) {
+      const double free_ratio = 1.0 - (double) used / capacity;
+      gclog_or_tty->print("Expand by free ratio: ");
+      gclog_or_tty->print("capacity : " SIZE_FORMAT ", ", capacity);
+      gclog_or_tty->print("used : " SIZE_FORMAT ", ", used);
+      gclog_or_tty->print_cr("free ratio : %f.2", free_ratio);
+    }
+
+    size_t available_bytes = max_size - capacity;
+    if (capacity < minimum_desired_capacity && available_bytes > 0) {
+      size_t young_gen_available_bytes = young->max_size() - young->capacity_in_bytes();
+      size_t old_gen_available_bytes = old->max_gen_size() - old->capacity_in_bytes();
+      size_t expand_bytes = minimum_desired_capacity - capacity;
+      if (isFullGC) {
+        size_t old_gen_expand_bytes =
+            (size_t) (expand_bytes * ((double) old_gen_available_bytes / available_bytes));
+        old->try_to_expand_by(old_gen_expand_bytes);
+      }
+      size_t young_gen_expand_bytes =
+          (size_t) (expand_bytes * ((double) young_gen_available_bytes / available_bytes));
+      young->try_to_expand_by(young_gen_expand_bytes);
+      return true;
+    }
+  }
+
+  return false;
+}