Merge
authorjwilhelm
Thu, 04 Feb 2016 00:53:31 +0100
changeset 35924 1d736ef364be
parent 35922 64f3032d733c (current diff)
parent 35923 45c44344f6b7 (diff)
child 35925 50501d0d9b2e
child 35929 2783e5e132e3
Merge
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/cms/TestBubbleUpRef.java	Thu Feb 04 00:53:31 2016 +0100
@@ -0,0 +1,186 @@
+/*
+ * 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" | vm.gc == "null"
+ * @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 -Xmx8m 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
+ *     -Xmx8m -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 ");
+        }
+    }
+}
+