test/gc/g1/TestShrinkAuxiliaryData.java

Print this page
rev 7970 : 8061715: gc/g1/TestShrinkAuxiliaryData15.java fails
Summary: added WhiteBox methods to count regions and exact aux data sizes
Reviewed-by:

*** 1,7 **** /* ! * 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. --- 1,7 ---- /* ! * Copyright (c) 2014, 2015, 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.
*** 19,29 **** * 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.OutputAnalyzer; import com.oracle.java.testlibrary.Platform; import com.oracle.java.testlibrary.ProcessTools; import com.oracle.java.testlibrary.Utils; import java.io.IOException; --- 19,29 ---- * 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 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,77 **** import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; ! import sun.misc.Unsafe; public class TestShrinkAuxiliaryData { private final static String[] initialOpts = new String[]{ "-XX:MinHeapFreeRatio=10", "-XX:MaxHeapFreeRatio=11", "-XX:+UseG1GC", ! "-XX:G1HeapRegionSize=1m", "-XX:-ExplicitGCInvokesConcurrent", ! "-XX:+PrintGCDetails" }; ! private final int RSetCacheSize; ! protected TestShrinkAuxiliaryData(int RSetCacheSize) { ! this.RSetCacheSize = RSetCacheSize; } protected void test() throws Exception { ArrayList<String> vmOpts = new ArrayList(); Collections.addAll(vmOpts, initialOpts); int maxCacheSize = Math.max(0, Math.min(31, getMaxCacheSize())); ! if (maxCacheSize < RSetCacheSize) { System.out.format("Skiping test for %d cache size due max cache size %d", ! RSetCacheSize, maxCacheSize ); return; } printTestInfo(maxCacheSize); ! vmOpts.add("-XX:G1ConcRSLogCacheSize=" + RSetCacheSize); vmOpts.addAll(Arrays.asList(Utils.getTestJavaOpts())); // for 32 bits ObjectAlignmentInBytes is not a option if (Platform.is32bit()) { ArrayList<String> vmOptsWithoutAlign = new ArrayList(vmOpts); --- 34,83 ---- import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; ! 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=" + REGION_SIZE, "-XX:-ExplicitGCInvokesConcurrent", ! "-XX:+PrintGCDetails", ! "-XX:+UnlockDiagnosticVMOptions", ! "-XX:+WhiteBoxAPI", ! "-Xbootclasspath/a:.", }; ! private final int hotCardTableSize; ! protected TestShrinkAuxiliaryData(int hotCardTableSize) { ! this.hotCardTableSize = hotCardTableSize; } protected void test() throws Exception { ArrayList<String> vmOpts = new ArrayList(); Collections.addAll(vmOpts, initialOpts); int maxCacheSize = Math.max(0, Math.min(31, getMaxCacheSize())); ! if (maxCacheSize < hotCardTableSize) { System.out.format("Skiping test for %d cache size due max cache size %d", ! hotCardTableSize, maxCacheSize ); return; } printTestInfo(maxCacheSize); ! vmOpts.add("-XX:G1ConcRSLogCacheSize=" + hotCardTableSize); vmOpts.addAll(Arrays.asList(Utils.getTestJavaOpts())); // for 32 bits ObjectAlignmentInBytes is not a option if (Platform.is32bit()) { ArrayList<String> vmOptsWithoutAlign = new ArrayList(vmOpts);
*** 95,120 **** = ProcessTools.createJavaProcessBuilder( opts.toArray(new String[opts.size()]) ); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } 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" + "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() - ShrinkAuxiliaryDataTest.getMemoryUsedByTest()), Unsafe.ADDRESS_SIZE, grouped.format((Runtime.getRuntime().freeMemory() - ShrinkAuxiliaryDataTest.getMemoryUsedByTest()) / Unsafe.ADDRESS_SIZE), --- 101,129 ---- = ProcessTools.createJavaProcessBuilder( opts.toArray(new String[opts.size()]) ); OutputAnalyzer output = new OutputAnalyzer(pb.start()); + System.out.println(output.getStdout()); + System.err.println(output.getStderr()); output.shouldHaveExitValue(0); } 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" + "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().maxMemory()), ! grouped.format(Runtime.getRuntime().maxMemory() - ShrinkAuxiliaryDataTest.getMemoryUsedByTest()), Unsafe.ADDRESS_SIZE, grouped.format((Runtime.getRuntime().freeMemory() - ShrinkAuxiliaryDataTest.getMemoryUsedByTest()) / Unsafe.ADDRESS_SIZE),
*** 133,160 **** 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 } } ! new ShrinkAuxiliaryDataTest().test(iterateCount); } class GarbageObject { private final List<byte[]> payload = new ArrayList(); --- 142,201 ---- 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 { ! 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(); ! System.out.println( "Page size = " + pageSize ! + " region size = " + REGION_SIZE ! + " aux data ~= " + (REGION_SIZE * 3 / 100)); ! // If auxdata size will be less than 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; } ! return true; } class GarbageObject { private final List<byte[]> payload = new ArrayList();
*** 175,219 **** } } private final List<GarbageObject> garbage = new ArrayList(); ! public void test(int num_iterate) throws IOException { allocate(); link(); mutate(); - deallocate(); ! MemoryUsage muBeforeHeap ! = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); ! MemoryUsage muBeforeNonHeap ! = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage(); ! 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() ) ); ! if (muAfterHeap.getCommitted() < muBeforeHeap.getCommitted()) { ! assertLessThanOrEqual(muAfterNonHeap.getCommitted(), muBeforeNonHeap.getCommitted(), ! String.format("non-heap decommit failed - after > before: %d > %d", ! muAfterNonHeap.getCommitted(), muBeforeNonHeap.getCommitted() ) ); } } --- 216,273 ---- } } private final List<GarbageObject> garbage = new ArrayList(); ! public void test() throws IOException { ! ! MemoryUsage muFull, muFree, muAuxDataFull, muAuxDataFree; ! float auxFull, auxFree; allocate(); link(); mutate(); ! muFull = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); ! long numUsedRegions = WhiteBox.getWhiteBox().g1NumMaxRegions() ! - WhiteBox.getWhiteBox().g1NumFreeRegions(); ! muAuxDataFull = WhiteBox.getWhiteBox().g1AuxiliaryMemoryUsage(); ! auxFull = (float)muAuxDataFull.getUsed() / numUsedRegions; ! System.out.format("Full aux data ratio= %f, regions max= %d, used= %d\n", ! auxFull, WhiteBox.getWhiteBox().g1NumMaxRegions(), numUsedRegions ! ); + deallocate(); System.gc(); ! ! muFree = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); ! muAuxDataFree = WhiteBox.getWhiteBox().g1AuxiliaryMemoryUsage(); ! ! numUsedRegions = WhiteBox.getWhiteBox().g1NumMaxRegions() ! - WhiteBox.getWhiteBox().g1NumFreeRegions(); ! auxFree = (float)muAuxDataFree.getUsed() / numUsedRegions; ! ! System.out.format("Free aux data ratio= %f, regions max= %d, used= %d\n", ! auxFree, WhiteBox.getWhiteBox().g1NumMaxRegions(), numUsedRegions ! ); ! ! Asserts.assertLessThanOrEqual(muFree.getCommitted(), muFull.getCommitted(), ! String.format("heap decommit failed - full > free: %d > %d", ! muFree.getCommitted(), muFull.getCommitted() ) ); ! System.out.format("State used committed\n"); ! System.out.format("Full aux data: %10d %10d\n", muAuxDataFull.getUsed(), muAuxDataFull.getCommitted()); ! System.out.format("Free aux data: %10d %10d\n", muAuxDataFree.getUsed(), muAuxDataFree.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 ) ); } }
*** 236,247 **** int regionNumber = ig / NUM_OBJECTS_PER_REGION; for (int i = 0; i < NUM_LINKS; i++) { int regionToLink; do { ! regionToLink = (int) (Math.random() ! * REGIONS_TO_ALLOCATE); } while (regionToLink == regionNumber); // get random garbage object from random region garbage.get(ig).addRef(garbage.get(regionToLink * NUM_OBJECTS_PER_REGION + (int) (Math.random() --- 290,300 ---- int regionNumber = ig / NUM_OBJECTS_PER_REGION; for (int i = 0; i < NUM_LINKS; i++) { int regionToLink; do { ! regionToLink = (int) (Math.random() * REGIONS_TO_ALLOCATE); } while (regionToLink == regionNumber); // get random garbage object from random region garbage.get(ig).addRef(garbage.get(regionToLink * NUM_OBJECTS_PER_REGION + (int) (Math.random()
*** 263,275 **** 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 NUM_OBJECTS_PER_REGION = 10; private static final int NUM_LINKS = 20; // how many links create for each object - } } --- 316,325 ---- static long getMemoryUsedByTest() { return REGIONS_TO_ALLOCATE * REGION_SIZE; } ! 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 } }