1 /* 2 * Copyright (c) 2011, 2018, 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 * @test 26 * @key stress gc 27 * 28 * @summary converted from VM Testbase gc/gctests/HeapUsageTest. 29 * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent, jrockit] 30 * VM Testbase readme: 31 * DESCRIPTION 32 * Originally it was Micro benchmark that tests the heap usage. 33 * 34 * COMMENTS 35 * This test was ported from JRockit test suite. 36 * 37 * @library /vmTestbase 38 * /test/lib 39 * @run driver jdk.test.lib.FileInstaller . . 40 * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.HeapUsageTest.HeapUsageTest 41 */ 42 43 package gc.gctests.HeapUsageTest; 44 45 import java.util.ArrayList; 46 import nsk.share.TestFailure; 47 import nsk.share.gc.GC; 48 import nsk.share.gc.GCTestBase; 49 import nsk.share.test.Stresser; 50 51 /** 52 * Micro benchmark that tests the heap usage. 53 */ 54 public class HeapUsageTest extends GCTestBase { 55 56 /** 57 * Helper class to store allocation size and iterations for the 58 * HeapUsageTest heap usage test program 59 */ 60 private class TestValue { 61 62 private int allocationSize; 63 private int allocationIterations; 64 65 TestValue(int allocSize, int allocIters) { 66 allocationSize = allocSize; 67 allocationIterations = allocIters; 68 } 69 70 final int getSize() { 71 return allocationSize; 72 } 73 74 final int getIterations() { 75 return allocationIterations; 76 } 77 } 78 79 /** 80 * Simple micro benchmark for testing heap usage. Returns a percentage 81 * that tells how much of the total heap size the test was able to 82 * allocate. 83 * 84 * @return success if test could run until OOME was thrown, and was 85 * able to determine the heap usage in percent without any other 86 * exceptions being thrown. 87 */ 88 public void run() { 89 90 try { 91 int[] testParams = 92 new int[]{512, 5, 2048, 3, 3145728, 2}; 93 94 95 TestValue[] values = new TestValue[testParams.length / 2]; 96 for (int i = 0; i < testParams.length / 2; i++) { 97 values[i] = new TestValue(testParams[i * 2], 98 testParams[i * 2 + 1]); 99 } 100 101 // NOTE: The call to Runtime might not look like it does anything 102 // here, but it codegens the class, so it will not OOM later on 103 // due to low-mem sitation for codegen. 104 Runtime r = Runtime.getRuntime(); 105 // NOTE: Codegen freeMemory() and maxMemory() so this 106 // doesn't cause OOM in a OOM situation 107 ArrayList holdObjects = new ArrayList(); 108 long currentAllocatedSize = 0; 109 Stresser stresser = new Stresser(runParams.getStressOptions()); 110 stresser.start(0); 111 try { 112 long loopCount; 113 int nrOfLoops = 0; 114 115 for (int i = 0; i < values.length; i++) { 116 if (values[i].getIterations() > nrOfLoops) { 117 nrOfLoops = values[i].getIterations(); 118 } 119 } 120 121 for (loopCount = 0;; loopCount++) { 122 for (int i = 0; i < nrOfLoops; i++) { 123 for (int k = 0; k < values.length; k++) { 124 if (i < values[k].getIterations()) { 125 if (!stresser.continueExecution()) { 126 // no time to eat all heap 127 return; 128 } 129 byte[] tmp = new byte[values[k].getSize()]; 130 holdObjects.add(tmp); 131 currentAllocatedSize += (long) values[k].getSize(); 132 } 133 } 134 } 135 } 136 } catch (OutOfMemoryError oome) { 137 long oomMaxMemory = r.maxMemory(); 138 139 holdObjects = null; 140 141 double myPercentUsed = 142 (((double) (currentAllocatedSize)) 143 / oomMaxMemory) * 100; 144 145 log.info("Heap usage percentage ( " 146 + myPercentUsed + " %) " + myPercentUsed); 147 } finally { 148 // NOTE: In case OOM wasn't hit, release references 149 // and cleanup by calling System.gc(); 150 holdObjects = null; 151 } 152 } catch (OutOfMemoryError oome2) { 153 throw new TestFailure("OutOfMemoryError thrown even though it shouldn't. " 154 + "Please investigate.", oome2); 155 } 156 } 157 158 public static void main(String[] args) { 159 GC.runTest(new HeapUsageTest(), args); 160 } 161 }