8146436: Add -XX:-ShrinkHeapInSteps option (previously -XX:+UseAggressiveHeapShrink)

Added ShrinkHeapInSteps option.

Reviewed-by: jmasa, tbenson
This commit is contained in:
Chris Plummer 2016-03-21 13:14:31 -07:00
parent ec9925fbe9
commit 4cc14cb17e
4 changed files with 94 additions and 27 deletions

View File

@ -254,19 +254,22 @@ void CardGeneration::compute_new_size() {
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;
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);
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");
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",

View File

@ -3272,6 +3272,11 @@ public:
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) \

View File

@ -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 @@ public class TestMaxMinHeapFreeRatioFlags {
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 @@ public class TestMaxMinHeapFreeRatioFlags {
* @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 @@ public class TestMaxMinHeapFreeRatioFlags {
"-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 class TestMaxMinHeapFreeRatioFlags {
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 @@ public class TestMaxMinHeapFreeRatioFlags {
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 @@ public class TestMaxMinHeapFreeRatioFlags {
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 @@ public class TestMaxMinHeapFreeRatioFlags {
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 @@ public class TestMaxMinHeapFreeRatioFlags {
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 class TestMaxMinHeapFreeRatioFlags {
}
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);

View File

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