1 /* 2 * Copyright (c) 2010, 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/huge/quicklook/largeheap/Access. 29 * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent] 30 * VM Testbase readme: 31 * DESCRIPTION 32 * The test is intended to test 64-bit VM for large memory and heap 33 * functionalities. This test checks that no unexpected exceptions and errors 34 * are thrown or the JVM is not crashed during allocation of different 35 * objects within 32-bit address range. 36 * First of all the test checks that the maximum amount of memory that 37 * the Java virtual machine will attempt to use (Runtime.maxMemory()) is 38 * greater than 4G. If that value is less than 4G, the test passes, otherwise 39 * it starts testing. 40 * A number of threads is started. That number is set in *.cfg file or is 41 * calculated by the test itself based on the machine (see 42 * nsk.share.gc.Algorithms.getThreadsCount() method). 43 * Each thread creates 9 arrays - one of each of the following types: byte, 44 * short, char, int, long, boolean, double, float, Object. All arrays have 45 * the same size, and that size is calculated so that all threads together are 46 * supposed to eat about 1.3G of the heap (30% of 4G). 47 * 48 * @library /vmTestbase 49 * /test/lib 50 * @run driver jdk.test.lib.FileInstaller . . 51 * @run main/othervm -XX:-UseGCOverheadLimit gc.huge.quicklook.largeheap.Access.access 52 */ 53 54 package gc.huge.quicklook.largeheap.Access; 55 56 import java.util.concurrent.ThreadLocalRandom; 57 import java.util.ArrayList; 58 import nsk.share.TestFailure; 59 import nsk.share.gc.*; 60 61 public class access extends ThreadedGCTest { 62 63 // The test should fill just about 30% of 4G range (32-bit address range) 64 final static double PART_OF_HEAP = 0.3; 65 final static long GIGOBYTE = 1024 * 1024 * 1024; 66 // Approximate number of bytes for one element of each tested type 67 // (byte, short, char, int, long, double, float, Object) 68 final static long TYPES_SIZE = 69 Memory.getByteSize() 70 + Memory.getShortSize() 71 + Memory.getIntSize() 72 + Memory.getCharSize() 73 + Memory.getLongSize() 74 + Memory.getDoubleSize() 75 + Memory.getFloatSize(); 76 //+ Memory.getBooleanSize() 77 //+ Memory.getReferenceObjectSize(); 78 private final static int STORAGE_SIZE_DIM1 = 65536; 79 private final static int STORAGE_SIZE_DIM2 = (int) (4 * GIGOBYTE / Memory.getLongSize() / STORAGE_SIZE_DIM1); 80 // An array to eat 4G of heap 81 private static long[][] storage = new long[STORAGE_SIZE_DIM1][]; 82 private volatile boolean is4GAllocated = false; 83 private final Object lock = new Object(); 84 85 private class Worker implements Runnable { 86 87 private int arraySize; 88 private ArrayList<Object> list; 89 Worker(int arraySize)90 public Worker(int arraySize) { 91 this.arraySize = arraySize; 92 list = new ArrayList<Object>(); 93 } 94 run()95 public void run() { 96 try { 97 synchronized (lock) { 98 while (!is4GAllocated && getExecutionController().continueExecution()) { 99 try { 100 lock.wait(100); 101 } catch (InterruptedException ie) { 102 } 103 } 104 } 105 while (getExecutionController().continueExecution()) { 106 byte[] barray = new byte[arraySize]; 107 short[] sarray = new short[arraySize]; 108 char[] carray = new char[arraySize]; 109 int[] iarray = new int[arraySize]; 110 long[] larray = new long[arraySize]; 111 double[] darray = new double[arraySize]; 112 float[] farray = new float[arraySize]; 113 list.add(barray); 114 list.add(sarray); 115 list.add(carray); 116 list.add(iarray); 117 list.add(larray); 118 list.add(darray); 119 list.add(darray); 120 for (int i = 0; i < arraySize; i++) { 121 larray[i] = (long) (i + 42); 122 darray[i] = (double) (42 * i); 123 farray[i] = (float) (0.6 * i); 124 if (i % 10000 == 0 && 125 getExecutionController().continueExecution()) { 126 return; 127 } 128 } 129 130 for (int i = arraySize - 1; i > 0; i -= 10) { 131 if (larray[i] != (long) (i + 42)) { 132 throw new TestFailure("The value = " 133 + larray[i] + " when expected =" 134 + (long) (i + 42)); 135 } 136 if (darray[i] - (double) (42 * i) > 0.001) { 137 throw new TestFailure("The value = " 138 + darray[i] + " when expected =" 139 + (double) (i + 42)); 140 } 141 if (farray[i] - (float) (0.6 * i) > 0.001) { 142 throw new TestFailure("The value = " 143 + farray[i] + " when expected =" 144 + (float) (i + 42)); 145 } 146 if (i % 10000 == 0 && 147 getExecutionController().continueExecution()) { 148 return; 149 } 150 } 151 for (Object obj : list) { 152 // check hashcode just to avoid optimization 153 if (obj.hashCode() == -1) { 154 throw new TestFailure("Unexpected hashcode"); 155 } 156 } 157 } 158 } finally { 159 list.clear(); 160 } 161 } 162 } 163 164 class MainWorker implements Runnable { 165 166 @Override run()167 public void run() { 168 synchronized (lock) { 169 for (int i = 0; i < STORAGE_SIZE_DIM1; i++) { 170 if (!getExecutionController().continueExecution()) { 171 log.debug("Test run out of time before 4G were allocated"); 172 lock.notifyAll(); 173 return; 174 } 175 storage[i] = new long[STORAGE_SIZE_DIM2]; 176 } 177 log.debug("The 4G are allocated, starting to test"); 178 is4GAllocated = true; 179 lock.notifyAll(); 180 } 181 ThreadLocalRandom random = ThreadLocalRandom.current(); 182 while (getExecutionController().continueExecution()) { 183 int i = random.nextInt(STORAGE_SIZE_DIM1); 184 int j = random.nextInt(STORAGE_SIZE_DIM2); 185 long value = random.nextLong(Long.MAX_VALUE); 186 storage[i][j] = value; 187 if (storage[i][j] != value) { 188 throw new TestFailure("The value = " 189 + storage[i][j] + " when expected =" 190 + value); 191 } 192 } 193 194 } 195 } 196 197 @Override run()198 public void run() { 199 if (testConditions()) { 200 super.run(); 201 } 202 } 203 204 @Override createRunnable(int i)205 protected Runnable createRunnable(int i) { 206 // Size of array for all types 207 long proposedSize = (long) ((Runtime.getRuntime().maxMemory() - 4 * GIGOBYTE * PART_OF_HEAP) 208 / (runParams.getNumberOfThreads() - 1) / TYPES_SIZE); 209 int arraySize = Algorithms.getArraySize(proposedSize); 210 if (i == 0) { 211 return new MainWorker(); 212 } 213 return new Worker(arraySize); 214 } 215 testConditions()216 public boolean testConditions() { 217 long maxMemory = Runtime.getRuntime().maxMemory(); 218 // If a machine has less than 4G for heap, there is nothing to test, 219 // so exit peacefully 220 if (maxMemory < 5 * GIGOBYTE) { 221 log.debug("Heap is less than 5G (" 222 + maxMemory + " bytes), nothing to " 223 + "test"); 224 return false; 225 } 226 return true; 227 } 228 main(String[] args)229 public static void main(String[] args) { 230 GC.runTest(new access(), args); 231 } 232 } 233