2
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
27
* @test TestSoftReferencesBehaviorOnOOME
29
* @summary Tests that all SoftReferences has been cleared at time of OOM.
30
* @requires vm.gc != "Z"
31
* @requires vm.gc != "Shenandoah"
33
* @modules java.base/jdk.internal.misc
34
* @run main/othervm -Xmx128m gc.TestSoftReferencesBehaviorOnOOME 512 2k
35
* @run main/othervm -Xmx128m gc.TestSoftReferencesBehaviorOnOOME 128k 256k
36
* @run main/othervm -Xmx128m gc.TestSoftReferencesBehaviorOnOOME 2k 32k
38
import jdk.test.lib.Utils;
39
import jdk.test.lib.Asserts;
40
import java.lang.ref.SoftReference;
41
import java.util.LinkedList;
42
import java.util.Random;
44
public class TestSoftReferencesBehaviorOnOOME {
47
* Test generates a lot of soft references to objects with random payloads.
48
* Then it provokes OOME and checks that all SoftReferences has been gone
49
* @param args - [minSize] [maxSize] [freq]
51
* - minSize - min size of random objects
52
* - maxSize - max size of random objects
54
public static void main(String[] args) {
55
long minSize = DEFAULT_MIN_SIZE;
56
long maxSize = DEFAULT_MAX_SIZE;
58
if ( args.length >= 2) {
59
maxSize = getBytesCount(args[1]);
62
if ( args.length >= 1) {
63
minSize = getBytesCount(args[0]);
66
new TestSoftReferencesBehaviorOnOOME().softReferencesOom(minSize, maxSize);
70
* Test that all SoftReferences has been cleared at time of OOM.
72
void softReferencesOom(long minSize, long maxSize) {
73
System.out.format( "minSize = %d, maxSize = %d%n", minSize, maxSize );
75
LinkedList<SoftReference<byte[]>> arrSoftRefs = new LinkedList<>();
76
staticRef = arrSoftRefs;
77
LinkedList<byte[]> arrObjects = new LinkedList<>();
78
staticRef = arrObjects;
80
long multiplier = maxSize - minSize;
81
long numberOfNotNulledObjects = 0;
85
// Lets allocate as many as we can - taking size of all SoftRerefences
86
// by minimum. So it can provoke some GC but we surely will allocate enough.
87
long numSofts = (long) ((0.95 * Runtime.getRuntime().totalMemory()) / minSize);
88
System.out.println("num Soft: " + numSofts);
90
while (numSofts-- > 0) {
91
int allocationSize = ((int) (RND_GENERATOR.nextDouble() * multiplier))
93
arrSoftRefs.add(new SoftReference<byte[]>(new byte[allocationSize]));
96
System.out.println("free: " + Runtime.getRuntime().freeMemory());
100
arrObjects.add(new byte[(int) Runtime.getRuntime().totalMemory()]);
103
} catch (OutOfMemoryError oome) {
105
// Clear allocated ballast, so we don't get another OOM.
108
long oomSoftArraySize = arrSoftRefs.size();
110
for (SoftReference<byte[]> sr : arrSoftRefs) {
114
numberOfNotNulledObjects++;
118
// Make sure we clear all refs before we return failure
120
Asserts.assertFalse(numberOfNotNulledObjects > 0,
121
"" + numberOfNotNulledObjects + " out of "
122
+ oomSoftArraySize + " SoftReferences was not "
123
+ "null at time of OutOfMemoryError"
126
Asserts.assertTrue(arrObjects == null, "OOME hasn't been provoked");
127
Asserts.assertTrue(arrSoftRefs == null, "OOME hasn't been provoked");
131
private static final long getBytesCount(String arg) {
132
String postfixes = "kMGT";
135
if (arg.trim().length() >= 2) {
136
mod = postfixes.indexOf(arg.trim().charAt(arg.length() - 1));
139
mod = (long) Math.pow(1024, mod+1);
140
arg = arg.substring(0, arg.length() - 1);
146
return Long.parseLong(arg) * mod;
149
private static final Random RND_GENERATOR = Utils.getRandomInstance();
150
private static final long DEFAULT_MIN_SIZE = 512;
151
private static final long DEFAULT_MAX_SIZE = 1024;
152
private static Object staticRef; // to prevent compile optimisations