1 /* 2 * Copyright (c) 2015,2016 Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package gc.g1.humongousObjects; 26 27 import gc.testlibrary.Helpers; 28 import jdk.test.lib.Asserts; 29 import sun.hotspot.WhiteBox; 30 31 /** 32 * @test TestHumongousThreshold 33 * @summary Checks that objects larger than half a region are allocated as humongous 34 * @requires vm.gc.G1 35 * @library /testlibrary /test/lib / 36 * @modules java.base/jdk.internal.misc 37 * @modules java.management 38 * @build sun.hotspot.WhiteBox 39 * gc.testlibrary.Helpers 40 * gc.g1.humongousObjects.TestHumongousThreshold 41 * @run driver ClassFileInstaller sun.hotspot.WhiteBox 42 * sun.hotspot.WhiteBox$WhiteBoxPermission 43 * 44 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 45 * -XX:G1HeapRegionSize=1M 46 * gc.g1.humongousObjects.TestHumongousThreshold 47 * 48 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 49 * -XX:G1HeapRegionSize=2M 50 * gc.g1.humongousObjects.TestHumongousThreshold 51 * 52 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 53 * -XX:G1HeapRegionSize=4M 54 * gc.g1.humongousObjects.TestHumongousThreshold 55 * 56 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 57 * -XX:G1HeapRegionSize=8M 58 * gc.g1.humongousObjects.TestHumongousThreshold 59 * 60 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 61 * -Xms128M -XX:G1HeapRegionSize=16M 62 * gc.g1.humongousObjects.TestHumongousThreshold 63 * 64 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 65 * -Xms200M -XX:G1HeapRegionSize=32M 66 * gc.g1.humongousObjects.TestHumongousThreshold 67 * 68 */ 69 70 public class TestHumongousThreshold { 71 private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 72 private static final int REGION_SIZE = WHITE_BOX.g1RegionSize(); 73 private static final int MAX_CONTINUOUS_SIZE_CHECK = 129; 74 private static final int NON_HUMONGOUS_STEPS = 10; 75 76 /** 77 * The method allocates byte[] with specified size and checks that: 78 * 1. byte[] is allocated as we specified in expectedHumongous. 79 * 2. byte[] is allocated as humongous if its size is large than a half of region and non-humongous otherwise. 80 * It uses WB to obtain the size of created byte[]. Only objects larger than half of region are expected 81 * to be humongous. 82 * 83 * @param arraySize size of allocation 84 * @param expectedHumongous expected humongous/non-humongous allocation 85 * @return allocated byte array 86 */ 87 88 private static void allocateAndCheck(int arraySize, boolean expectedHumongous) { 89 byte[] storage = new byte[arraySize]; 90 long objectSize = WHITE_BOX.getObjectSize(storage); 91 boolean shouldBeHumongous = objectSize > (REGION_SIZE / 2); 92 93 Asserts.assertEquals(expectedHumongous, shouldBeHumongous, "Despite we expected this object to be " 94 + (expectedHumongous ? "humongous" : "non-humongous") + " it appeared otherwise when we checked " 95 + "object size - likely test bug; Allocation size = " + arraySize + "; Object size = " + objectSize 96 + "; region size = " + REGION_SIZE); 97 98 Asserts.assertEquals(WHITE_BOX.g1IsHumongous(storage), shouldBeHumongous, 99 "Object should be allocated as " + (shouldBeHumongous ? "humongous" 100 : "non-humongous") + " but it wasn't; Allocation size = " + arraySize + "; Object size = " 101 + objectSize + "; region size = " + REGION_SIZE); 102 } 103 104 public static void main(String[] args) { 105 int byteArrayMemoryOverhead = Helpers.detectByteArrayAllocationOverhead(); 106 107 // Largest non-humongous byte[] 108 int maxByteArrayNonHumongousSize = (REGION_SIZE / 2) - byteArrayMemoryOverhead; 109 110 // Increment for non-humongous testing 111 int nonHumongousStep = maxByteArrayNonHumongousSize / NON_HUMONGOUS_STEPS; 112 113 // Maximum byte[] that takes one region 114 int maxByteArrayOneRegionSize = REGION_SIZE - byteArrayMemoryOverhead; 115 116 // Sizes in regions 117 // i,e, 1.0f means one region, 1.5f means one and half region etc 118 float[] humongousFactors = {0.8f, 1.0f, 1.2f, 1.5f, 1.7f, 2.0f, 2.5f}; 119 120 // Some diagnostic output 121 System.out.format("%s started%n", TestHumongousThreshold.class.getName()); 122 System.out.format("Actual G1 region size %d%n", REGION_SIZE); 123 System.out.format("byte[] memory overhead %d%n", byteArrayMemoryOverhead); 124 125 // Non-humongous allocations 126 System.out.format("Doing non-humongous allocations%n"); 127 128 // Testing allocations with byte[] with length from 0 to MAX_CONTINUOUS_SIZE_CHECK 129 System.out.format("Testing allocations with byte[] with length from 0 to %d%n", MAX_CONTINUOUS_SIZE_CHECK); 130 for (int i = 0; i < MAX_CONTINUOUS_SIZE_CHECK; ++i) { 131 allocateAndCheck(i, false); 132 } 133 134 // Testing allocations with byte[] with length from 0 to nonHumongousStep * NON_HUMONGOUS_STEPS 135 System.out.format("Testing allocations with byte[] with length from 0 to %d with step %d%n", 136 nonHumongousStep * NON_HUMONGOUS_STEPS, nonHumongousStep); 137 for (int i = 0; i < NON_HUMONGOUS_STEPS; ++i) { 138 allocateAndCheck(i * nonHumongousStep, false); 139 } 140 141 // Testing allocations with byte[] of maximum non-humongous length 142 System.out.format("Testing allocations with byte[] of maximum non-humongous length %d%n", 143 maxByteArrayNonHumongousSize); 144 allocateAndCheck(maxByteArrayNonHumongousSize, false); 145 146 // Humongous allocations 147 System.out.format("Doing humongous allocations%n"); 148 // Testing with minimum humongous object 149 System.out.format("Testing with byte[] of minimum humongous object %d%n", maxByteArrayNonHumongousSize + 1); 150 allocateAndCheck(maxByteArrayNonHumongousSize + 1, true); 151 152 // Testing allocations with byte[] with length from (maxByteArrayNonHumongousSize + 1) to 153 // (maxByteArrayNonHumongousSize + 1 + MAX_CONTINUOUS_SIZE_CHECK) 154 System.out.format("Testing allocations with byte[] with length from %d to %d%n", 155 maxByteArrayNonHumongousSize + 1, maxByteArrayNonHumongousSize + 1 + MAX_CONTINUOUS_SIZE_CHECK); 156 for (int i = 0; i < MAX_CONTINUOUS_SIZE_CHECK; ++i) { 157 allocateAndCheck(maxByteArrayNonHumongousSize + 1 + i, true); 158 } 159 160 // Checking that large (more than a half of region size) objects are humongous 161 System.out.format("Checking that large (more than a half of region size) objects are humongous%n"); 162 for (float factor : humongousFactors) { 163 allocateAndCheck((int) (maxByteArrayOneRegionSize * factor), true); 164 } 165 } 166 }