test/gc/g1/TestShrinkAuxiliaryData.java

Print this page
rev 7802 : 8061715:gc/g1/TestShrinkAuxiliaryData15.java fails

@@ -19,11 +19,11 @@
  * 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 static com.oracle.java.testlibrary.Asserts.assertLessThanOrEqual;
+import com.oracle.java.testlibrary.Asserts;
 import com.oracle.java.testlibrary.OutputAnalyzer;
 import com.oracle.java.testlibrary.Platform;
 import com.oracle.java.testlibrary.ProcessTools;
 import com.oracle.java.testlibrary.Utils;
 import java.io.IOException;

@@ -34,21 +34,27 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
-import sun.misc.Unsafe;
+import sun.misc.Unsafe; // for ADDRESS_SIZE
+import sun.hotspot.WhiteBox;
 
 public class TestShrinkAuxiliaryData {
 
+    private static final int REGION_SIZE = 1024 * 1024;
+
     private final static String[] initialOpts = new String[]{
         "-XX:MinHeapFreeRatio=10",
         "-XX:MaxHeapFreeRatio=11",
         "-XX:+UseG1GC",
-        "-XX:G1HeapRegionSize=1m",
+        "-XX:G1HeapRegionSize=" + REGION_SIZE,
         "-XX:-ExplicitGCInvokesConcurrent",
-        "-XX:+PrintGCDetails"
+        "-XX:+PrintGCDetails",
+        "-XX:+UnlockDiagnosticVMOptions",
+        "-XX:+WhiteBoxAPI",
+        "-Xbootclasspath/a:.",
     };
 
     private final int RSetCacheSize;
 
     protected TestShrinkAuxiliaryData(int RSetCacheSize) {

@@ -96,25 +102,27 @@
                 opts.toArray(new String[opts.size()])
         );
 
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldHaveExitValue(0);
+        System.out.println(output.getOutput());
     }
 
     private void printTestInfo(int maxCacheSize) {
 
         DecimalFormat grouped = new DecimalFormat("000,000");
         DecimalFormatSymbols formatSymbols = grouped.getDecimalFormatSymbols();
         formatSymbols.setGroupingSeparator(' ');
         grouped.setDecimalFormatSymbols(formatSymbols);
 
-        System.out.format("Test will use %s bytes of memory of %s available%n"
+        System.out.format(
+                "Test will use %s bytes of memory of %s available%n"
                 + "Available memory is %s with %d bytes pointer size - can save %s pointers%n"
                 + "Max cache size: 2^%d = %s elements%n",
                 grouped.format(ShrinkAuxiliaryDataTest.getMemoryUsedByTest()),
-                grouped.format(Runtime.getRuntime().freeMemory()),
-                grouped.format(Runtime.getRuntime().freeMemory()
+                grouped.format(Runtime.getRuntime().maxMemory()),
+                grouped.format(Runtime.getRuntime().maxMemory()
                         - ShrinkAuxiliaryDataTest.getMemoryUsedByTest()),
                 Unsafe.ADDRESS_SIZE,
                 grouped.format((Runtime.getRuntime().freeMemory()
                         - ShrinkAuxiliaryDataTest.getMemoryUsedByTest())
                         / Unsafe.ADDRESS_SIZE),

@@ -133,28 +141,57 @@
         long availableMemory = Runtime.getRuntime().freeMemory()
                 - ShrinkAuxiliaryDataTest.getMemoryUsedByTest() - 1l;
         if (availableMemory <= 0) {
             return 0;
         }
+
         long availablePointersCount = availableMemory / Unsafe.ADDRESS_SIZE;
         return (63 - (int) Long.numberOfLeadingZeros(availablePointersCount));
     }
 
     static class ShrinkAuxiliaryDataTest {
 
         public static void main(String[] args) throws IOException {
-            int iterateCount = DEFAULT_ITERATION_COUNT;
 
-            if (args.length > 0) {
-                try {
-                    iterateCount = Integer.parseInt(args[0]);
-                } catch (NumberFormatException e) {
-                    //num_iterate remains default
+            ShrinkAuxiliaryDataTest testCase = new ShrinkAuxiliaryDataTest();
+
+            if (!testCase.checkEnvApplicability()) {
+                return;
+            }
+
+            testCase.test();
+        }
+
+        /**
+         * Checks is this environment suitable to run this test
+         * - memory is enough to decommit (page size is not big)
+         * - RSet cache size is not too big
+         *
+         * @return true if test could run, false if test should be skipped
+         */
+        protected boolean checkEnvApplicability() {
+
+            int pageSize = WhiteBox.getWhiteBox().getVMPageSize();
+            // if Auxdata size will be more that page size it wouldn't decommit
+            // auxiliary data size is about ~3.6% of heap size
+            if (pageSize > REGION_SIZE * 3 / 100) {
+                System.out.format("Skipping test for too large page size = %d",
+                       pageSize
+                );
+                return false;
                 }
+
+            if (REGION_SIZE * REGIONS_TO_ALLOCATE > Runtime.getRuntime().maxMemory()) {
+                System.out.format("Skipping test for too low available memory. "
+                        + "Need %d, available %d",
+                        REGION_SIZE * REGIONS_TO_ALLOCATE,
+                        Runtime.getRuntime().maxMemory()
+                );
+                return false;
             }
 
-            new ShrinkAuxiliaryDataTest().test(iterateCount);
+            return true;
         }
 
         class GarbageObject {
 
             private final List<byte[]> payload = new ArrayList();

@@ -175,45 +212,54 @@
             }
         }
 
         private final List<GarbageObject> garbage = new ArrayList();
 
-        public void test(int num_iterate) throws IOException {
+        public void test() throws IOException {
+
+            MemoryUsage muFull, muFree, muAuxData;
+            float auxFull, auxFree;
 
             allocate();
             link();
             mutate();
-            deallocate();
 
-            MemoryUsage muBeforeHeap
-                        = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
-            MemoryUsage muBeforeNonHeap
-                        = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
+            muFull = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
+            long numCommittedRegions = muFull.getCommitted() / WhiteBox.getWhiteBox().g1RegionSize();
+            muAuxData = WhiteBox.getWhiteBox().g1AuxiliaryMemoryUsage();
+            auxFull = (float)muAuxData.getUsed() / numCommittedRegions;
+
+            System.out.format("Full aux data ratio= %f, regions comm= %d, busy= %d\n",
+                    auxFull, numCommittedRegions,
+                    numCommittedRegions - (int)WhiteBox.getWhiteBox().g1NumFreeRegions()
+            );
 
-            for (int i = 0; i < num_iterate; i++) {
-                allocate();
-                link();
-                mutate();
                 deallocate();
-            }
-
             System.gc();
-            MemoryUsage muAfterHeap
-                        = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
-            MemoryUsage muAfterNonHeap
-                        = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
-
-            assertLessThanOrEqual(muAfterHeap.getCommitted(), muBeforeHeap.getCommitted(),
-                    String.format("heap decommit failed - after > before: %d > %d",
-                            muAfterHeap.getCommitted(), muBeforeHeap.getCommitted()
+
+            muFree = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
+            muAuxData = WhiteBox.getWhiteBox().g1AuxiliaryMemoryUsage();
+
+            numCommittedRegions = muFree.getCommitted() / WhiteBox.getWhiteBox().g1RegionSize();
+            auxFree = (float)muAuxData.getUsed() / numCommittedRegions;
+
+            System.out.format("Free aux data ratio= %f, regions comm= %d, busy= %d\n",
+                    auxFree, numCommittedRegions,
+                    numCommittedRegions - (int)WhiteBox.getWhiteBox().g1NumFreeRegions()
+            );
+
+            Asserts.assertLessThanOrEqual(muFree.getCommitted(), muFull.getCommitted(),
+                    String.format("heap decommit failed - full > free: %d > %d",
+                            muFree.getCommitted(), muFull.getCommitted()
                     )
             );
 
-            if (muAfterHeap.getCommitted() < muBeforeHeap.getCommitted()) {
-                assertLessThanOrEqual(muAfterNonHeap.getCommitted(), muBeforeNonHeap.getCommitted(),
-                        String.format("non-heap decommit failed - after > before: %d > %d",
-                                muAfterNonHeap.getCommitted(), muBeforeNonHeap.getCommitted()
+            // if decommited check that aux data has same ratio
+            if (muFree.getCommitted() < muFull.getCommitted()) {
+                Asserts.assertLessThanOrEqual(auxFree, auxFull,
+                        String.format("auxiliary data decommit failed - full > free: %f > %f",
+                                auxFree, auxFull
                         )
                 );
             }
         }
 

@@ -263,13 +309,10 @@
 
         static long getMemoryUsedByTest() {
             return REGIONS_TO_ALLOCATE * REGION_SIZE;
         }
 
-        private static final int REGION_SIZE = 1024 * 1024;
-        private static final int DEFAULT_ITERATION_COUNT = 1;   // iterate main scenario
-        private static final int REGIONS_TO_ALLOCATE = 5;
+        private static final int REGIONS_TO_ALLOCATE = 100;
         private static final int NUM_OBJECTS_PER_REGION = 10;
         private static final int NUM_LINKS = 20; // how many links create for each object
-
     }
 }