diff --git a/.hgtags b/.hgtags index bc582c580eb1515d1ed6b1fa7b34dd129bc38a03..2f0d9eba7acac69ea8ffba9f250b8f3240a55133 100644 --- a/.hgtags +++ b/.hgtags @@ -820,6 +820,7 @@ ca3b8c8e390ab0540b0cc2e5def869b38e460d86 jdk8u75-b01 916712f178c39d0acbc590f38802133fc86a7346 jdk8u75-b06 8c791dd1c24d85ebd18b03d49185c2a25263c129 jdk8u75-b07 e4a935cb6f7178912fd653e2a9514eadec7935ab jdk8u75-b08 +e97c45c377eb8d022cfe24b73737fa312107e0a5 jdk8u75-b09 d7b01fb81aa8a5437cb03bc36afe15cf0e55fb89 jdk8u76-b00 c1679cc87ba045219169cabb6b9b378c2b5cc578 jdk8u76-b01 218483967e52b419d885d34af4488a81c5133804 jdk8u76-b02 @@ -829,4 +830,5 @@ c1679cc87ba045219169cabb6b9b378c2b5cc578 jdk8u76-b01 6449ee3bf707225372709ac830524c00984c601f jdk8u76-b06 7d1074c74d6000ec8257917ebfcee3fed4249f7d jdk8u76-b07 392f8722fc513e28f78c5c563d51af7dc8466b29 jdk8u76-b08 +3bf0f5b8a892defd0bf9731b4e15926881fcda74 jdk8u76-b09 b374548dcb4834eb8731a06b52faddd0f10bd45d jdk8u81-b00 diff --git a/test/gc/TestSoftReferencesBehaviorOnOOME.java b/test/gc/TestSoftReferencesBehaviorOnOOME.java new file mode 100644 index 0000000000000000000000000000000000000000..55fa59885e163c220f1dc803fa2fe605b9e1ffa2 --- /dev/null +++ b/test/gc/TestSoftReferencesBehaviorOnOOME.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2014 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 TestSoftReferencesBehaviorOnOOME + * @key gc + * @summary Tests that all SoftReferences has been cleared at time of OOM. + * @library /testlibrary + * @build TestSoftReferencesBehaviorOnOOME + * @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 512 2k + * @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 128k 256k + * @run main/othervm -Xmx128m TestSoftReferencesBehaviorOnOOME 2k 32k 10 + */ +import java.util.*; +import com.oracle.java.testlibrary.Utils; +import java.lang.ref.SoftReference; +import java.util.LinkedList; + +public class TestSoftReferencesBehaviorOnOOME { + + private static final Random rndGenerator = new Random(); + + public static void main(String[] args) { + int semiRefAllocFrequency = DEFAULT_FREQUENCY; + long minSize = DEFAULT_MIN_SIZE, + maxSize = DEFAULT_MAX_SIZE; + + if ( args.length >= 3 ) { + semiRefAllocFrequency = Integer.parseInt(args[2]); + } + + if ( args.length >= 2) { + maxSize = getBytesCount(args[1]); + } + + if ( args.length >= 1) { + minSize = getBytesCount(args[0]); + } + + new TestSoftReferencesBehaviorOnOOME().softReferencesOom(minSize, maxSize, semiRefAllocFrequency); + } + + /** + * Test that all SoftReferences has been cleared at time of OOM. + */ + void softReferencesOom(long minSize, long maxSize, int semiRefAllocFrequency) { + System.out.format( "minSize = %d, maxSize = %d, freq = %d%n", minSize, maxSize, semiRefAllocFrequency ); + long counter = 0; + + long multiplier = maxSize - minSize; + LinkedList arrSoftRefs = new LinkedList(); + LinkedList arrObjects = new LinkedList(); + long numberOfNotNulledObjects = 0; + long oomSoftArraySize = 0; + + try { + while (true) { + // Keep every Xth object to make sure we hit OOM pretty fast + if (counter % semiRefAllocFrequency != 0) { + long allocationSize = ((int) (rndGenerator.nextDouble() * multiplier)) + + minSize; + arrObjects.add(new byte[(int)allocationSize]); + } else { + arrSoftRefs.add(new SoftReference(new Object())); + } + + counter++; + if (counter == Long.MAX_VALUE) { + counter = 0; + } + } + } catch (OutOfMemoryError oome) { + // Clear allocated ballast, so we don't get another OOM. + + arrObjects = null; + + // Get the number of soft refs first, so we don't trigger + // another OOM. + oomSoftArraySize = arrSoftRefs.size(); + + for (SoftReference sr : arrSoftRefs) { + Object o = sr.get(); + + if (o != null) { + numberOfNotNulledObjects++; + } + } + + // Make sure we clear all refs before we return failure + arrSoftRefs = null; + + if (numberOfNotNulledObjects > 0) { + throw new RuntimeException(numberOfNotNulledObjects + " out of " + + oomSoftArraySize + " SoftReferences was not " + + "null at time of OutOfMemoryError"); + } + } finally { + arrSoftRefs = null; + arrObjects = null; + } + } + + private static final long getBytesCount(String arg) { + String postfixes = "kMGT"; + long mod = 1; + + if (arg.trim().length() >= 2) { + mod = postfixes.indexOf( + arg.trim().charAt(arg.length() - 1) + ); + + if (mod != -1) { + mod = (long) Math.pow(1024, mod+1); + arg = arg.substring(0, arg.length() - 1); + } else { + mod = 1; // 10^0 + } + } + + return Long.parseLong(arg) * mod; + } + + private static final long DEFAULT_MIN_SIZE = 512; + private static final long DEFAULT_MAX_SIZE = 1024; + private static final int DEFAULT_FREQUENCY = 4; +}