Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/test/gc/g1/TestShrinkAuxiliaryData.java
32284 views
/*1* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import com.oracle.java.testlibrary.Asserts;24import com.oracle.java.testlibrary.OutputAnalyzer;25import com.oracle.java.testlibrary.Platform;26import com.oracle.java.testlibrary.ProcessTools;27import com.oracle.java.testlibrary.Utils;28import java.io.IOException;29import java.lang.management.ManagementFactory;30import java.lang.management.MemoryUsage;31import java.text.DecimalFormat;32import java.text.DecimalFormatSymbols;33import java.util.ArrayList;34import java.util.Arrays;35import java.util.Collections;36import java.util.LinkedList;37import java.util.List;38import sun.misc.Unsafe; // for ADDRESS_SIZE39import sun.hotspot.WhiteBox;4041public class TestShrinkAuxiliaryData {4243private static final int REGION_SIZE = 1024 * 1024;4445private final static String[] initialOpts = new String[]{46"-XX:MinHeapFreeRatio=10",47"-XX:MaxHeapFreeRatio=11",48"-XX:+UseG1GC",49"-XX:G1HeapRegionSize=" + REGION_SIZE,50"-XX:-ExplicitGCInvokesConcurrent",51"-XX:+PrintGCDetails",52"-XX:+UnlockDiagnosticVMOptions",53"-XX:+WhiteBoxAPI",54"-Xbootclasspath/a:.",55};5657private final int hotCardTableSize;5859protected TestShrinkAuxiliaryData(int hotCardTableSize) {60this.hotCardTableSize = hotCardTableSize;61}6263protected void test() throws Exception {64ArrayList<String> vmOpts = new ArrayList();65Collections.addAll(vmOpts, initialOpts);6667int maxCacheSize = Math.max(0, Math.min(31, getMaxCacheSize()));68if (maxCacheSize < hotCardTableSize) {69System.out.format("Skiping test for %d cache size due max cache size %d",70hotCardTableSize, maxCacheSize71);72return;73}7475printTestInfo(maxCacheSize);7677vmOpts.add("-XX:G1ConcRSLogCacheSize=" + hotCardTableSize);78vmOpts.addAll(Arrays.asList(Utils.getTestJavaOpts()));7980// for 32 bits ObjectAlignmentInBytes is not a option81if (Platform.is32bit()) {82ArrayList<String> vmOptsWithoutAlign = new ArrayList(vmOpts);83vmOptsWithoutAlign.add(ShrinkAuxiliaryDataTest.class.getName());84performTest(vmOptsWithoutAlign);85return;86}8788for (int alignment = 3; alignment <= 8; alignment++) {89ArrayList<String> vmOptsWithAlign = new ArrayList(vmOpts);90vmOptsWithAlign.add("-XX:ObjectAlignmentInBytes="91+ (int) Math.pow(2, alignment));92vmOptsWithAlign.add(ShrinkAuxiliaryDataTest.class.getName());9394performTest(vmOptsWithAlign);95}96}9798private void performTest(List<String> opts) throws Exception {99ProcessBuilder pb100= ProcessTools.createJavaProcessBuilder(101opts.toArray(new String[opts.size()])102);103104OutputAnalyzer output = new OutputAnalyzer(pb.start());105System.out.println(output.getStdout());106System.err.println(output.getStderr());107output.shouldHaveExitValue(0);108}109110private void printTestInfo(int maxCacheSize) {111112DecimalFormat grouped = new DecimalFormat("000,000");113DecimalFormatSymbols formatSymbols = grouped.getDecimalFormatSymbols();114formatSymbols.setGroupingSeparator(' ');115grouped.setDecimalFormatSymbols(formatSymbols);116117System.out.format(118"Test will use %s bytes of memory of %s available%n"119+ "Available memory is %s with %d bytes pointer size - can save %s pointers%n"120+ "Max cache size: 2^%d = %s elements%n",121grouped.format(ShrinkAuxiliaryDataTest.getMemoryUsedByTest()),122grouped.format(Runtime.getRuntime().maxMemory()),123grouped.format(Runtime.getRuntime().maxMemory()124- ShrinkAuxiliaryDataTest.getMemoryUsedByTest()),125Unsafe.ADDRESS_SIZE,126grouped.format((Runtime.getRuntime().freeMemory()127- ShrinkAuxiliaryDataTest.getMemoryUsedByTest())128/ Unsafe.ADDRESS_SIZE),129maxCacheSize,130grouped.format((int) Math.pow(2, maxCacheSize))131);132}133134/**135* Detects maximum possible size of G1ConcRSLogCacheSize available for136* current process based on maximum available process memory size137*138* @return power of two139*/140private static int getMaxCacheSize() {141long availableMemory = Runtime.getRuntime().freeMemory()142- ShrinkAuxiliaryDataTest.getMemoryUsedByTest() - 1l;143if (availableMemory <= 0) {144return 0;145}146147long availablePointersCount = availableMemory / Unsafe.ADDRESS_SIZE;148return (63 - (int) Long.numberOfLeadingZeros(availablePointersCount));149}150151static class ShrinkAuxiliaryDataTest {152153public static void main(String[] args) throws IOException {154155ShrinkAuxiliaryDataTest testCase = new ShrinkAuxiliaryDataTest();156157if (!testCase.checkEnvApplicability()) {158return;159}160161testCase.test();162}163164/**165* Checks is this environment suitable to run this test166* - memory is enough to decommit (page size is not big)167* - RSet cache size is not too big168*169* @return true if test could run, false if test should be skipped170*/171protected boolean checkEnvApplicability() {172173int pageSize = WhiteBox.getWhiteBox().getVMPageSize();174System.out.println( "Page size = " + pageSize175+ " region size = " + REGION_SIZE176+ " aux data ~= " + (REGION_SIZE * 3 / 100));177// If auxdata size will be less than page size it wouldn't decommit.178// Auxiliary data size is about ~3.6% of heap size.179if (pageSize >= REGION_SIZE * 3 / 100) {180System.out.format("Skipping test for too large page size = %d",181pageSize182);183return false;184}185186if (REGION_SIZE * REGIONS_TO_ALLOCATE > Runtime.getRuntime().maxMemory()) {187System.out.format("Skipping test for too low available memory. "188+ "Need %d, available %d",189REGION_SIZE * REGIONS_TO_ALLOCATE,190Runtime.getRuntime().maxMemory()191);192return false;193}194195return true;196}197198class GarbageObject {199200private final List<byte[]> payload = new ArrayList();201private final List<GarbageObject> ref = new LinkedList();202203public GarbageObject(int size) {204payload.add(new byte[size]);205}206207public void addRef(GarbageObject g) {208ref.add(g);209}210211public void mutate() {212if (!payload.isEmpty() && payload.get(0).length > 0) {213payload.get(0)[0] = (byte) (Math.random() * Byte.MAX_VALUE);214}215}216}217218private final List<GarbageObject> garbage = new ArrayList();219220public void test() throws IOException {221222MemoryUsage muFull, muFree, muAuxDataFull, muAuxDataFree;223float auxFull, auxFree;224225allocate();226link();227mutate();228229muFull = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();230long numUsedRegions = WhiteBox.getWhiteBox().g1NumMaxRegions()231- WhiteBox.getWhiteBox().g1NumFreeRegions();232muAuxDataFull = WhiteBox.getWhiteBox().g1AuxiliaryMemoryUsage();233auxFull = (float)muAuxDataFull.getUsed() / numUsedRegions;234235System.out.format("Full aux data ratio= %f, regions max= %d, used= %d\n",236auxFull, WhiteBox.getWhiteBox().g1NumMaxRegions(), numUsedRegions237);238239deallocate();240System.gc();241242muFree = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();243muAuxDataFree = WhiteBox.getWhiteBox().g1AuxiliaryMemoryUsage();244245numUsedRegions = WhiteBox.getWhiteBox().g1NumMaxRegions()246- WhiteBox.getWhiteBox().g1NumFreeRegions();247auxFree = (float)muAuxDataFree.getUsed() / numUsedRegions;248249System.out.format("Free aux data ratio= %f, regions max= %d, used= %d\n",250auxFree, WhiteBox.getWhiteBox().g1NumMaxRegions(), numUsedRegions251);252253Asserts.assertLessThanOrEqual(muFree.getCommitted(), muFull.getCommitted(),254String.format("heap decommit failed - full > free: %d > %d",255muFree.getCommitted(), muFull.getCommitted()256)257);258259System.out.format("State used committed\n");260System.out.format("Full aux data: %10d %10d\n", muAuxDataFull.getUsed(), muAuxDataFull.getCommitted());261System.out.format("Free aux data: %10d %10d\n", muAuxDataFree.getUsed(), muAuxDataFree.getCommitted());262263// if decommited check that aux data has same ratio264if (muFree.getCommitted() < muFull.getCommitted()) {265Asserts.assertLessThanOrEqual(auxFree, auxFull,266String.format("auxiliary data decommit failed - full > free: %f > %f",267auxFree, auxFull268)269);270}271}272273private void allocate() {274for (int r = 0; r < REGIONS_TO_ALLOCATE; r++) {275for (int i = 0; i < NUM_OBJECTS_PER_REGION; i++) {276GarbageObject g = new GarbageObject(REGION_SIZE277/ NUM_OBJECTS_PER_REGION);278garbage.add(g);279}280}281}282283/**284* Iterate through all allocated objects, and link to objects in another285* regions286*/287private void link() {288for (int ig = 0; ig < garbage.size(); ig++) {289int regionNumber = ig / NUM_OBJECTS_PER_REGION;290291for (int i = 0; i < NUM_LINKS; i++) {292int regionToLink;293do {294regionToLink = (int) (Math.random() * REGIONS_TO_ALLOCATE);295} while (regionToLink == regionNumber);296297// get random garbage object from random region298garbage.get(ig).addRef(garbage.get(regionToLink299* NUM_OBJECTS_PER_REGION + (int) (Math.random()300* NUM_OBJECTS_PER_REGION)));301}302}303}304305private void mutate() {306for (int ig = 0; ig < garbage.size(); ig++) {307garbage.get(ig).mutate();308}309}310311private void deallocate() {312garbage.clear();313System.gc();314}315316static long getMemoryUsedByTest() {317return REGIONS_TO_ALLOCATE * REGION_SIZE;318}319320private static final int REGIONS_TO_ALLOCATE = 100;321private static final int NUM_OBJECTS_PER_REGION = 10;322private static final int NUM_LINKS = 20; // how many links create for each object323}324}325326327