8146436: Add -XX:-ShrinkHeapInSteps option (previously -XX:+UseAggressiveHeapShrink)
Summary: Added ShrinkHeapInSteps option.
Reviewed-by: jmasa, tbenson
--- a/hotspot/src/share/vm/gc/shared/cardGeneration.cpp Mon Mar 21 12:52:24 2016 +0100
+++ b/hotspot/src/share/vm/gc/shared/cardGeneration.cpp Mon Mar 21 13:14:31 2016 -0700
@@ -254,19 +254,22 @@
if (capacity_after_gc > maximum_desired_capacity) {
// Capacity too large, compute shrinking size
shrink_bytes = capacity_after_gc - maximum_desired_capacity;
- // We don't want shrink all the way back to initSize if people call
- // System.gc(), because some programs do that between "phases" and then
- // we'd just have to grow the heap up again for the next phase. So we
- // damp the shrinking: 0% on the first call, 10% on the second call, 40%
- // on the third call, and 100% by the fourth call. But if we recompute
- // size without shrinking, it goes back to 0%.
- shrink_bytes = shrink_bytes / 100 * current_shrink_factor;
+ if (ShrinkHeapInSteps) {
+ // If ShrinkHeapInSteps is true (the default),
+ // we don't want to shrink all the way back to initSize if people call
+ // System.gc(), because some programs do that between "phases" and then
+ // we'd just have to grow the heap up again for the next phase. So we
+ // damp the shrinking: 0% on the first call, 10% on the second call, 40%
+ // on the third call, and 100% by the fourth call. But if we recompute
+ // size without shrinking, it goes back to 0%.
+ shrink_bytes = shrink_bytes / 100 * current_shrink_factor;
+ if (current_shrink_factor == 0) {
+ _shrink_factor = 10;
+ } else {
+ _shrink_factor = MIN2(current_shrink_factor * 4, (size_t) 100);
+ }
+ }
assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size");
- if (current_shrink_factor == 0) {
- _shrink_factor = 10;
- } else {
- _shrink_factor = MIN2(current_shrink_factor * 4, (size_t) 100);
- }
log_trace(gc, heap)(" shrinking: initSize: %.1fK maximum_desired_capacity: %.1fK",
initial_size() / (double) K, maximum_desired_capacity / (double) K);
log_trace(gc, heap)(" shrink_bytes: %.1fK current_shrink_factor: " SIZE_FORMAT " new shrink factor: " SIZE_FORMAT " _min_heap_delta_bytes: %.1fK",
--- a/hotspot/src/share/vm/runtime/globals.hpp Mon Mar 21 12:52:24 2016 +0100
+++ b/hotspot/src/share/vm/runtime/globals.hpp Mon Mar 21 13:14:31 2016 -0700
@@ -3272,6 +3272,11 @@
range(0, 100) \
constraint(MaxHeapFreeRatioConstraintFunc,AfterErgo) \
\
+ product(bool, ShrinkHeapInSteps, true, \
+ "When disabled, informs the GC to shrink the java heap directly" \
+ " to the target size at the next full GC rather than requiring" \
+ " smaller steps during multiple full GCs.") \
+ \
product(intx, SoftRefLRUPolicyMSPerMB, 1000, \
"Number of milliseconds per MB of free space in the heap") \
range(0, max_intx) \
--- a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Mon Mar 21 12:52:24 2016 +0100
+++ b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Mon Mar 21 13:14:31 2016 -0700
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,11 +61,11 @@
negativeTest(-1, false, 50, false, options);
negativeTest(50, true, -1, true, options);
- positiveTest(10, false, 90, false, options);
- positiveTest(10, true, 80, false, options);
- positiveTest(20, false, 70, true, options);
- positiveTest(25, true, 65, true, options);
- positiveTest(40, false, 50, false, options);
+ positiveTest(10, false, 90, false, true, options);
+ positiveTest(10, true, 80, false, true, options);
+ positiveTest(20, false, 70, true, true, options);
+ positiveTest(25, true, 65, true, true, options);
+ positiveTest(40, false, 50, false, true, options);
}
/**
@@ -79,7 +79,7 @@
* @param options additional options for JVM
*/
public static void positiveTest(int minRatio, boolean useXminf,
- int maxRatio, boolean useXmaxf,
+ int maxRatio, boolean useXmaxf, boolean shrinkHeapInSteps,
LinkedList<String> options) throws Exception {
LinkedList<String> vmOptions = new LinkedList<>(options);
@@ -90,9 +90,11 @@
"-Xms" + HEAP_SIZE,
"-XX:NewSize=" + NEW_SIZE,
"-XX:MaxNewSize=" + MAX_NEW_SIZE,
+ "-XX:" + (shrinkHeapInSteps ? '+' : '-') + "ShrinkHeapInSteps",
RatioVerifier.class.getName(),
Integer.toString(minRatio),
- Integer.toString(maxRatio)
+ Integer.toString(maxRatio),
+ Boolean.toString(shrinkHeapInSteps)
);
ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
@@ -151,8 +153,8 @@
public static LinkedList<Object> garbage = new LinkedList<>();
public static void main(String args[]) throws Exception {
- if (args.length != 2) {
- throw new IllegalArgumentException("Expected 2 args: <minRatio> <maxRatio>");
+ if (args.length != 3) {
+ throw new IllegalArgumentException("Expected 3 args: <minRatio> <maxRatio> <shrinkHeapInSteps>");
}
if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.PSOld) {
System.out.println("Test is not applicable to parallel GC");
@@ -161,8 +163,10 @@
double minRatio = Integer.valueOf(args[0]) / 100.0;
double maxRatio = Integer.valueOf(args[1]) / 100.0;
+ boolean shrinkHeapInSteps = Boolean.valueOf(args[2]);
long maxHeapSize = getMax();
+ int gcTries = (shrinkHeapInSteps ? GC_TRIES : 1);
// commit 0.5 of total heap size to have enough space
// to both shink and expand
@@ -170,7 +174,7 @@
garbage.add(new byte[ARRAY_LENGTH]);
}
- forceGC();
+ forceGC(gcTries);
// Verify that current heap free ratio lies between specified limits
verifyRatio(minRatio, maxRatio);
@@ -185,7 +189,7 @@
memoryToFill -= CHUNK_SIZE;
}
- forceGC();
+ forceGC(gcTries);
// Verify that after memory allocation heap free ratio is still conforming specified limits
verifyRatio(minRatio, maxRatio);
// Verify that heap was actually expanded
@@ -204,7 +208,7 @@
memoryToFree -= CHUNK_SIZE;
}
- forceGC();
+ forceGC(gcTries);
// Verify that heap free ratio is still conforming specified limits
verifyRatio(minRatio, maxRatio);
// Verify that heap was actually shrinked
@@ -214,8 +218,8 @@
}
- public static void forceGC() {
- for (int i = 0; i < GC_TRIES; i++) {
+ public static void forceGC(int gcTries) {
+ for (int i = 0; i < gcTries; i++) {
System.gc();
try {
Thread.sleep(10);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/arguments/TestShrinkHeapInSteps.java Mon Mar 21 13:14:31 2016 -0700
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestShrinkHeapInSteps
+ * @key gc
+ * @summary Verify that -XX:-ShrinkHeapInSteps works properly.
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ * java.management
+ * @build TestMaxMinHeapFreeRatioFlags TestShrinkHeapInSteps
+ * @run driver/timeout=240 TestShrinkHeapInSteps
+ */
+
+import java.util.LinkedList;
+import java.util.Arrays;
+import java.util.Collections;
+import jdk.test.lib.Utils;
+
+public class TestShrinkHeapInSteps {
+ public static void main(String args[]) throws Exception {
+ LinkedList<String> options = new LinkedList<>(
+ Arrays.asList(Utils.getFilteredTestJavaOpts("-XX:[^ ]*HeapFreeRatio","-XX:\\+ExplicitGCInvokesConcurrent"))
+ );
+
+ // Leverage the existing TestMaxMinHeapFreeRatioFlags test, but pass
+ // "false" for the shrinkHeapInSteps argument. This will cause it to
+ // run with -XX:-ShrinkHeapInSteps, and only do 1 full GC instead of 10.
+ TestMaxMinHeapFreeRatioFlags.positiveTest(10, false, 90, false, false, options);
+ TestMaxMinHeapFreeRatioFlags.positiveTest(10, true, 80, false, false, options);
+ TestMaxMinHeapFreeRatioFlags.positiveTest(20, false, 70, true, false, options);
+ TestMaxMinHeapFreeRatioFlags.positiveTest(25, true, 65, true, false, options);
+ TestMaxMinHeapFreeRatioFlags.positiveTest(40, false, 50, false, false, options);
+ }
+}