3ba0af5c09
Reviewed-by: jmasa, sangheki, kzhaldyb
187 lines
5.9 KiB
Java
187 lines
5.9 KiB
Java
/*
|
|
* Copyright (c) 2004, 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.
|
|
*/
|
|
|
|
import java.lang.ref.ReferenceQueue;
|
|
import java.lang.ref.WeakReference;
|
|
import java.util.LinkedList;
|
|
import java.util.ListIterator;
|
|
|
|
/*
|
|
* @test
|
|
* @requires vm.gc.ConcMarkSweep
|
|
* @key cte_test
|
|
* @bug 4950157
|
|
* @summary Stress the behavior of ergonomics when the heap is nearly full and
|
|
* stays nearly full.
|
|
* @run main/othervm
|
|
* -XX:+UseConcMarkSweepGC -XX:-CMSYield -XX:-CMSPrecleanRefLists1
|
|
* -XX:CMSInitiatingOccupancyFraction=0 -Xmx80m TestBubbleUpRef 16000 50 10000
|
|
*/
|
|
|
|
/**
|
|
* Test program to stress the behavior of ergonomics when the
|
|
* heap is nearly full and stays nearly full.
|
|
* This is a test to catch references that have been discovered
|
|
* during concurrent marking and whose referents have been
|
|
* cleared by the mutator.
|
|
* Allocate objects with weak references until the heap is full
|
|
* Free the objects.
|
|
* Do work so that concurrent marking has a chance to work
|
|
* Clear the referents out of the weak references
|
|
* System.gc() in the hopes that it will acquire the collection
|
|
* Free the weak references
|
|
* Do it again.
|
|
*
|
|
* Use the following VM options
|
|
* -Xmx80m -XX:-CMSYield [-XX:+UseConcMarkSweepGC] -XX:-CMSPrecleanRefLists1
|
|
* -XX:CMSInitiatingOccupancyFraction=0
|
|
*
|
|
* Use parameter:
|
|
* args[0] - array size (16000)
|
|
* args[1] - iterations (50)
|
|
* args[2] - work (10000)
|
|
*/
|
|
class MyList extends LinkedList {
|
|
|
|
int[] a;
|
|
|
|
MyList(int size) {
|
|
a = new int[size];
|
|
}
|
|
}
|
|
|
|
class MyRefList extends LinkedList {
|
|
|
|
WeakReference ref;
|
|
|
|
MyRefList(Object o, ReferenceQueue rq) {
|
|
ref = new WeakReference(o, rq);
|
|
}
|
|
|
|
void clearReferent() {
|
|
ref.clear();
|
|
}
|
|
}
|
|
|
|
public class TestBubbleUpRef {
|
|
|
|
MyList list;
|
|
MyRefList refList;
|
|
ReferenceQueue rq;
|
|
int refListLen;
|
|
int arraySize;
|
|
int iterations;
|
|
int workUnits;
|
|
|
|
TestBubbleUpRef(int as, int cnt, int wk) {
|
|
arraySize = as;
|
|
iterations = cnt;
|
|
workUnits = wk;
|
|
list = new MyList(arraySize);
|
|
refList = new MyRefList(list, rq);
|
|
}
|
|
|
|
public void fill() {
|
|
System.out.println("fill() " + iterations + " times");
|
|
int count = 0;
|
|
while (true) {
|
|
try {
|
|
// Allocations
|
|
MyList next = new MyList(arraySize);
|
|
list.add(next);
|
|
MyRefList nextRef = new MyRefList(next, rq);
|
|
refList.add(nextRef);
|
|
} catch (OutOfMemoryError e) {
|
|
// When the heap is full
|
|
try {
|
|
if (count++ > iterations) {
|
|
return;
|
|
}
|
|
System.out.println("Freeing list");
|
|
while (!list.isEmpty()) {
|
|
list.removeFirst();
|
|
}
|
|
System.out.println("Doing work");
|
|
int j = 0;
|
|
for (int i = 1; i < workUnits; i++) {
|
|
j = j + i;
|
|
}
|
|
System.out.println("Clearing refs");
|
|
ListIterator listIt = refList.listIterator();
|
|
while (listIt.hasNext()) {
|
|
MyRefList next = (MyRefList) listIt.next();
|
|
next.clearReferent();
|
|
}
|
|
System.gc();
|
|
System.out.println("Freeing refs");
|
|
while (!refList.isEmpty()) {
|
|
refList.removeFirst();
|
|
}
|
|
} catch (OutOfMemoryError e2) {
|
|
System.err.println("Out of Memory - 2 ");
|
|
continue;
|
|
}
|
|
} catch (Exception e) {
|
|
System.err.println("Unexpected exception: " + e);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test entry point.
|
|
* args[0] - array size (is the size of the int array in a list item)
|
|
* args[1] - iterations (is the number of out-of-memory exceptions before exit)
|
|
* args[2] - work (is the work done between allocations)
|
|
* @param args
|
|
*/
|
|
public static void main(String[] args) {
|
|
// Get the input parameters.
|
|
if (args.length != 3) {
|
|
throw new IllegalArgumentException("Wrong number of input argumets");
|
|
}
|
|
|
|
int as = Integer.parseInt(args[0]);
|
|
int cnt = Integer.parseInt(args[1]);
|
|
int work = Integer.parseInt(args[2]);
|
|
|
|
System.out.println("<array size> " + as + "\n"
|
|
+ "<OOM's> " + cnt + "\n"
|
|
+ "<work units> " + work + "\n");
|
|
|
|
// Initialization
|
|
TestBubbleUpRef b = new TestBubbleUpRef(as, cnt, work);
|
|
|
|
// Run the test
|
|
try {
|
|
b.fill();
|
|
} catch (OutOfMemoryError e) {
|
|
b = null; // Free memory before trying to print anything
|
|
System.err.println("Out of Memory - exiting ");
|
|
} catch (Exception e) {
|
|
System.err.println("Exiting ");
|
|
}
|
|
}
|
|
}
|
|
|