test/gc/g1/TestShrinkAuxiliaryData.java

Mon, 06 Nov 2017 16:51:47 +0800

author
aoqi
date
Mon, 06 Nov 2017 16:51:47 +0800
changeset 7997
6cbff0651f1a
parent 7835
e5406a79ae90
permissions
-rw-r--r--

[Code Reorganization] remove trailing whitespace to pass jcheck test

tschatzl@7255 1 /*
azakharov@7835 2 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
tschatzl@7255 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
tschatzl@7255 4 *
tschatzl@7255 5 * This code is free software; you can redistribute it and/or modify it
tschatzl@7255 6 * under the terms of the GNU General Public License version 2 only, as
tschatzl@7255 7 * published by the Free Software Foundation.
tschatzl@7255 8 *
tschatzl@7255 9 * This code is distributed in the hope that it will be useful, but WITHOUT
tschatzl@7255 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
tschatzl@7255 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
tschatzl@7255 12 * version 2 for more details (a copy is included in the LICENSE file that
tschatzl@7255 13 * accompanied this code).
tschatzl@7255 14 *
tschatzl@7255 15 * You should have received a copy of the GNU General Public License version
tschatzl@7255 16 * 2 along with this work; if not, write to the Free Software Foundation,
tschatzl@7255 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
tschatzl@7255 18 *
tschatzl@7255 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
tschatzl@7255 20 * or visit www.oracle.com if you need additional information or have any
tschatzl@7255 21 * questions.
tschatzl@7255 22 */
tschatzl@7255 23
azakharov@7835 24 import com.oracle.java.testlibrary.Asserts;
tschatzl@7255 25 import com.oracle.java.testlibrary.OutputAnalyzer;
tschatzl@7255 26 import com.oracle.java.testlibrary.Platform;
tschatzl@7255 27 import com.oracle.java.testlibrary.ProcessTools;
tschatzl@7255 28 import com.oracle.java.testlibrary.Utils;
tschatzl@7255 29 import java.io.IOException;
tschatzl@7255 30 import java.lang.management.ManagementFactory;
tschatzl@7255 31 import java.lang.management.MemoryUsage;
tschatzl@7255 32 import java.text.DecimalFormat;
tschatzl@7255 33 import java.text.DecimalFormatSymbols;
tschatzl@7255 34 import java.util.ArrayList;
tschatzl@7255 35 import java.util.Arrays;
tschatzl@7255 36 import java.util.Collections;
tschatzl@7255 37 import java.util.LinkedList;
tschatzl@7255 38 import java.util.List;
azakharov@7835 39 import sun.misc.Unsafe; // for ADDRESS_SIZE
azakharov@7835 40 import sun.hotspot.WhiteBox;
tschatzl@7255 41
tschatzl@7255 42 public class TestShrinkAuxiliaryData {
tschatzl@7255 43
azakharov@7835 44 private static final int REGION_SIZE = 1024 * 1024;
azakharov@7835 45
tschatzl@7255 46 private final static String[] initialOpts = new String[]{
tschatzl@7255 47 "-XX:MinHeapFreeRatio=10",
tschatzl@7255 48 "-XX:MaxHeapFreeRatio=11",
tschatzl@7255 49 "-XX:+UseG1GC",
azakharov@7835 50 "-XX:G1HeapRegionSize=" + REGION_SIZE,
azakharov@7337 51 "-XX:-ExplicitGCInvokesConcurrent",
azakharov@7835 52 "-XX:+PrintGCDetails",
azakharov@7835 53 "-XX:+UnlockDiagnosticVMOptions",
azakharov@7835 54 "-XX:+WhiteBoxAPI",
azakharov@7835 55 "-Xbootclasspath/a:.",
tschatzl@7255 56 };
tschatzl@7255 57
azakharov@7835 58 private final int hotCardTableSize;
tschatzl@7255 59
azakharov@7835 60 protected TestShrinkAuxiliaryData(int hotCardTableSize) {
azakharov@7835 61 this.hotCardTableSize = hotCardTableSize;
tschatzl@7255 62 }
tschatzl@7255 63
tschatzl@7255 64 protected void test() throws Exception {
tschatzl@7255 65 ArrayList<String> vmOpts = new ArrayList();
tschatzl@7255 66 Collections.addAll(vmOpts, initialOpts);
tschatzl@7255 67
tschatzl@7255 68 int maxCacheSize = Math.max(0, Math.min(31, getMaxCacheSize()));
azakharov@7835 69 if (maxCacheSize < hotCardTableSize) {
tschatzl@7255 70 System.out.format("Skiping test for %d cache size due max cache size %d",
azakharov@7835 71 hotCardTableSize, maxCacheSize
tschatzl@7255 72 );
tschatzl@7255 73 return;
tschatzl@7255 74 }
tschatzl@7255 75
tschatzl@7255 76 printTestInfo(maxCacheSize);
tschatzl@7255 77
azakharov@7835 78 vmOpts.add("-XX:G1ConcRSLogCacheSize=" + hotCardTableSize);
jwilhelm@7785 79 vmOpts.addAll(Arrays.asList(Utils.getTestJavaOpts()));
tschatzl@7255 80
tschatzl@7255 81 // for 32 bits ObjectAlignmentInBytes is not a option
tschatzl@7255 82 if (Platform.is32bit()) {
tschatzl@7255 83 ArrayList<String> vmOptsWithoutAlign = new ArrayList(vmOpts);
tschatzl@7255 84 vmOptsWithoutAlign.add(ShrinkAuxiliaryDataTest.class.getName());
tschatzl@7255 85 performTest(vmOptsWithoutAlign);
tschatzl@7255 86 return;
tschatzl@7255 87 }
tschatzl@7255 88
tschatzl@7255 89 for (int alignment = 3; alignment <= 8; alignment++) {
tschatzl@7255 90 ArrayList<String> vmOptsWithAlign = new ArrayList(vmOpts);
tschatzl@7255 91 vmOptsWithAlign.add("-XX:ObjectAlignmentInBytes="
tschatzl@7255 92 + (int) Math.pow(2, alignment));
tschatzl@7255 93 vmOptsWithAlign.add(ShrinkAuxiliaryDataTest.class.getName());
tschatzl@7255 94
tschatzl@7255 95 performTest(vmOptsWithAlign);
tschatzl@7255 96 }
tschatzl@7255 97 }
tschatzl@7255 98
tschatzl@7255 99 private void performTest(List<String> opts) throws Exception {
tschatzl@7255 100 ProcessBuilder pb
azakharov@7835 101 = ProcessTools.createJavaProcessBuilder(
azakharov@7835 102 opts.toArray(new String[opts.size()])
azakharov@7835 103 );
tschatzl@7255 104
tschatzl@7255 105 OutputAnalyzer output = new OutputAnalyzer(pb.start());
azakharov@7835 106 System.out.println(output.getStdout());
azakharov@7835 107 System.err.println(output.getStderr());
tschatzl@7255 108 output.shouldHaveExitValue(0);
tschatzl@7255 109 }
tschatzl@7255 110
tschatzl@7255 111 private void printTestInfo(int maxCacheSize) {
tschatzl@7255 112
tschatzl@7255 113 DecimalFormat grouped = new DecimalFormat("000,000");
tschatzl@7255 114 DecimalFormatSymbols formatSymbols = grouped.getDecimalFormatSymbols();
tschatzl@7255 115 formatSymbols.setGroupingSeparator(' ');
tschatzl@7255 116 grouped.setDecimalFormatSymbols(formatSymbols);
tschatzl@7255 117
azakharov@7835 118 System.out.format(
azakharov@7835 119 "Test will use %s bytes of memory of %s available%n"
tschatzl@7255 120 + "Available memory is %s with %d bytes pointer size - can save %s pointers%n"
tschatzl@7255 121 + "Max cache size: 2^%d = %s elements%n",
tschatzl@7255 122 grouped.format(ShrinkAuxiliaryDataTest.getMemoryUsedByTest()),
azakharov@7835 123 grouped.format(Runtime.getRuntime().maxMemory()),
azakharov@7835 124 grouped.format(Runtime.getRuntime().maxMemory()
tschatzl@7255 125 - ShrinkAuxiliaryDataTest.getMemoryUsedByTest()),
tschatzl@7255 126 Unsafe.ADDRESS_SIZE,
tschatzl@7255 127 grouped.format((Runtime.getRuntime().freeMemory()
tschatzl@7255 128 - ShrinkAuxiliaryDataTest.getMemoryUsedByTest())
tschatzl@7255 129 / Unsafe.ADDRESS_SIZE),
tschatzl@7255 130 maxCacheSize,
tschatzl@7255 131 grouped.format((int) Math.pow(2, maxCacheSize))
tschatzl@7255 132 );
tschatzl@7255 133 }
tschatzl@7255 134
tschatzl@7255 135 /**
tschatzl@7255 136 * Detects maximum possible size of G1ConcRSLogCacheSize available for
tschatzl@7255 137 * current process based on maximum available process memory size
tschatzl@7255 138 *
tschatzl@7255 139 * @return power of two
tschatzl@7255 140 */
tschatzl@7255 141 private static int getMaxCacheSize() {
tschatzl@7255 142 long availableMemory = Runtime.getRuntime().freeMemory()
tschatzl@7255 143 - ShrinkAuxiliaryDataTest.getMemoryUsedByTest() - 1l;
tschatzl@7255 144 if (availableMemory <= 0) {
tschatzl@7255 145 return 0;
tschatzl@7255 146 }
azakharov@7835 147
tschatzl@7255 148 long availablePointersCount = availableMemory / Unsafe.ADDRESS_SIZE;
tschatzl@7255 149 return (63 - (int) Long.numberOfLeadingZeros(availablePointersCount));
tschatzl@7255 150 }
tschatzl@7255 151
tschatzl@7255 152 static class ShrinkAuxiliaryDataTest {
tschatzl@7255 153
tschatzl@7255 154 public static void main(String[] args) throws IOException {
tschatzl@7255 155
azakharov@7835 156 ShrinkAuxiliaryDataTest testCase = new ShrinkAuxiliaryDataTest();
azakharov@7835 157
azakharov@7835 158 if (!testCase.checkEnvApplicability()) {
azakharov@7835 159 return;
tschatzl@7255 160 }
tschatzl@7255 161
azakharov@7835 162 testCase.test();
azakharov@7835 163 }
azakharov@7835 164
azakharov@7835 165 /**
azakharov@7835 166 * Checks is this environment suitable to run this test
azakharov@7835 167 * - memory is enough to decommit (page size is not big)
azakharov@7835 168 * - RSet cache size is not too big
azakharov@7835 169 *
azakharov@7835 170 * @return true if test could run, false if test should be skipped
azakharov@7835 171 */
azakharov@7835 172 protected boolean checkEnvApplicability() {
azakharov@7835 173
azakharov@7835 174 int pageSize = WhiteBox.getWhiteBox().getVMPageSize();
azakharov@7835 175 System.out.println( "Page size = " + pageSize
azakharov@7835 176 + " region size = " + REGION_SIZE
azakharov@7835 177 + " aux data ~= " + (REGION_SIZE * 3 / 100));
azakharov@7835 178 // If auxdata size will be less than page size it wouldn't decommit.
azakharov@7835 179 // Auxiliary data size is about ~3.6% of heap size.
azakharov@7835 180 if (pageSize >= REGION_SIZE * 3 / 100) {
azakharov@7835 181 System.out.format("Skipping test for too large page size = %d",
azakharov@7835 182 pageSize
azakharov@7835 183 );
azakharov@7835 184 return false;
azakharov@7835 185 }
azakharov@7835 186
azakharov@7835 187 if (REGION_SIZE * REGIONS_TO_ALLOCATE > Runtime.getRuntime().maxMemory()) {
azakharov@7835 188 System.out.format("Skipping test for too low available memory. "
azakharov@7835 189 + "Need %d, available %d",
azakharov@7835 190 REGION_SIZE * REGIONS_TO_ALLOCATE,
azakharov@7835 191 Runtime.getRuntime().maxMemory()
azakharov@7835 192 );
azakharov@7835 193 return false;
azakharov@7835 194 }
azakharov@7835 195
azakharov@7835 196 return true;
tschatzl@7255 197 }
tschatzl@7255 198
tschatzl@7255 199 class GarbageObject {
tschatzl@7255 200
tschatzl@7255 201 private final List<byte[]> payload = new ArrayList();
tschatzl@7255 202 private final List<GarbageObject> ref = new LinkedList();
tschatzl@7255 203
tschatzl@7255 204 public GarbageObject(int size) {
tschatzl@7255 205 payload.add(new byte[size]);
tschatzl@7255 206 }
tschatzl@7255 207
tschatzl@7255 208 public void addRef(GarbageObject g) {
tschatzl@7255 209 ref.add(g);
tschatzl@7255 210 }
tschatzl@7255 211
tschatzl@7255 212 public void mutate() {
tschatzl@7255 213 if (!payload.isEmpty() && payload.get(0).length > 0) {
tschatzl@7255 214 payload.get(0)[0] = (byte) (Math.random() * Byte.MAX_VALUE);
tschatzl@7255 215 }
tschatzl@7255 216 }
tschatzl@7255 217 }
tschatzl@7255 218
tschatzl@7255 219 private final List<GarbageObject> garbage = new ArrayList();
tschatzl@7255 220
azakharov@7835 221 public void test() throws IOException {
azakharov@7835 222
azakharov@7835 223 MemoryUsage muFull, muFree, muAuxDataFull, muAuxDataFree;
azakharov@7835 224 float auxFull, auxFree;
tschatzl@7255 225
tschatzl@7255 226 allocate();
tschatzl@7255 227 link();
tschatzl@7255 228 mutate();
azakharov@7835 229
azakharov@7835 230 muFull = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
azakharov@7835 231 long numUsedRegions = WhiteBox.getWhiteBox().g1NumMaxRegions()
azakharov@7835 232 - WhiteBox.getWhiteBox().g1NumFreeRegions();
azakharov@7835 233 muAuxDataFull = WhiteBox.getWhiteBox().g1AuxiliaryMemoryUsage();
azakharov@7835 234 auxFull = (float)muAuxDataFull.getUsed() / numUsedRegions;
azakharov@7835 235
azakharov@7835 236 System.out.format("Full aux data ratio= %f, regions max= %d, used= %d\n",
azakharov@7835 237 auxFull, WhiteBox.getWhiteBox().g1NumMaxRegions(), numUsedRegions
azakharov@7835 238 );
azakharov@7835 239
tschatzl@7255 240 deallocate();
azakharov@7835 241 System.gc();
tschatzl@7255 242
azakharov@7835 243 muFree = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
azakharov@7835 244 muAuxDataFree = WhiteBox.getWhiteBox().g1AuxiliaryMemoryUsage();
tschatzl@7255 245
azakharov@7835 246 numUsedRegions = WhiteBox.getWhiteBox().g1NumMaxRegions()
azakharov@7835 247 - WhiteBox.getWhiteBox().g1NumFreeRegions();
azakharov@7835 248 auxFree = (float)muAuxDataFree.getUsed() / numUsedRegions;
tschatzl@7255 249
azakharov@7835 250 System.out.format("Free aux data ratio= %f, regions max= %d, used= %d\n",
azakharov@7835 251 auxFree, WhiteBox.getWhiteBox().g1NumMaxRegions(), numUsedRegions
azakharov@7835 252 );
tschatzl@7255 253
azakharov@7835 254 Asserts.assertLessThanOrEqual(muFree.getCommitted(), muFull.getCommitted(),
azakharov@7835 255 String.format("heap decommit failed - full > free: %d > %d",
azakharov@7835 256 muFree.getCommitted(), muFull.getCommitted()
tschatzl@7255 257 )
tschatzl@7255 258 );
tschatzl@7255 259
azakharov@7835 260 System.out.format("State used committed\n");
azakharov@7835 261 System.out.format("Full aux data: %10d %10d\n", muAuxDataFull.getUsed(), muAuxDataFull.getCommitted());
azakharov@7835 262 System.out.format("Free aux data: %10d %10d\n", muAuxDataFree.getUsed(), muAuxDataFree.getCommitted());
azakharov@7835 263
azakharov@7835 264 // if decommited check that aux data has same ratio
azakharov@7835 265 if (muFree.getCommitted() < muFull.getCommitted()) {
azakharov@7835 266 Asserts.assertLessThanOrEqual(auxFree, auxFull,
azakharov@7835 267 String.format("auxiliary data decommit failed - full > free: %f > %f",
azakharov@7835 268 auxFree, auxFull
tschatzl@7255 269 )
tschatzl@7255 270 );
tschatzl@7255 271 }
tschatzl@7255 272 }
tschatzl@7255 273
tschatzl@7255 274 private void allocate() {
tschatzl@7255 275 for (int r = 0; r < REGIONS_TO_ALLOCATE; r++) {
tschatzl@7255 276 for (int i = 0; i < NUM_OBJECTS_PER_REGION; i++) {
tschatzl@7255 277 GarbageObject g = new GarbageObject(REGION_SIZE
tschatzl@7255 278 / NUM_OBJECTS_PER_REGION);
tschatzl@7255 279 garbage.add(g);
tschatzl@7255 280 }
tschatzl@7255 281 }
tschatzl@7255 282 }
tschatzl@7255 283
tschatzl@7255 284 /**
tschatzl@7255 285 * Iterate through all allocated objects, and link to objects in another
tschatzl@7255 286 * regions
tschatzl@7255 287 */
tschatzl@7255 288 private void link() {
tschatzl@7255 289 for (int ig = 0; ig < garbage.size(); ig++) {
tschatzl@7255 290 int regionNumber = ig / NUM_OBJECTS_PER_REGION;
tschatzl@7255 291
tschatzl@7255 292 for (int i = 0; i < NUM_LINKS; i++) {
tschatzl@7255 293 int regionToLink;
tschatzl@7255 294 do {
azakharov@7835 295 regionToLink = (int) (Math.random() * REGIONS_TO_ALLOCATE);
tschatzl@7255 296 } while (regionToLink == regionNumber);
tschatzl@7255 297
tschatzl@7255 298 // get random garbage object from random region
tschatzl@7255 299 garbage.get(ig).addRef(garbage.get(regionToLink
tschatzl@7255 300 * NUM_OBJECTS_PER_REGION + (int) (Math.random()
tschatzl@7255 301 * NUM_OBJECTS_PER_REGION)));
tschatzl@7255 302 }
tschatzl@7255 303 }
tschatzl@7255 304 }
tschatzl@7255 305
tschatzl@7255 306 private void mutate() {
tschatzl@7255 307 for (int ig = 0; ig < garbage.size(); ig++) {
tschatzl@7255 308 garbage.get(ig).mutate();
tschatzl@7255 309 }
tschatzl@7255 310 }
tschatzl@7255 311
tschatzl@7255 312 private void deallocate() {
tschatzl@7255 313 garbage.clear();
tschatzl@7255 314 System.gc();
tschatzl@7255 315 }
tschatzl@7255 316
tschatzl@7255 317 static long getMemoryUsedByTest() {
tschatzl@7255 318 return REGIONS_TO_ALLOCATE * REGION_SIZE;
tschatzl@7255 319 }
tschatzl@7255 320
azakharov@7835 321 private static final int REGIONS_TO_ALLOCATE = 100;
tschatzl@7255 322 private static final int NUM_OBJECTS_PER_REGION = 10;
tschatzl@7255 323 private static final int NUM_LINKS = 20; // how many links create for each object
tschatzl@7255 324 }
tschatzl@7255 325 }

mercurial