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
}
}