1 /*
   2 * Copyright (c) 2015, 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 package jdk.test.lib;
  25 
  26 import java.util.LinkedList;
  27 import java.util.concurrent.Callable;
  28 
  29 /**
  30  * Helper class which allocates memory.
  31  *
  32  * Typical usage:
  33  * <pre>
  34  * {@code
  35  *           AllocationHelper allocator = new AllocationHelper(MAX_ITERATIONS, ARRAY_LENGTH, CHUNK_SIZE,
  36  *                   () -> (verifier()));
  37  *           // Allocate byte[CHUNK_SIZE] ARRAY_LENGTH times. Total allocated bytes will be CHUNK_SIZE * ARRAY_LENGTH + refs length.
  38  *           // Then invoke verifier and iterate MAX_ITERATIONS times.
  39  *           allocator.allocateMemoryAndVerify();
  40  * }
  41  * </pre>
  42  */
  43 public final class AllocationHelper {
  44 
  45     private final int arrayLength;
  46     private final int maxIterations;
  47     private final int chunkSize;
  48 
  49     // garbageStorage is used to store link to garbage to prevent optimization.
  50     private static Object garbageStorage;
  51     private byte garbage[][];
  52     private final Callable<?> verifierInstance;
  53 
  54     /**
  55      * Create an AllocationHelper with specified iteration count, array length, chunk size and verifier.
  56      *
  57      * @param maxIterations
  58      * @param arrayLength
  59      * @param chunkSize
  60      * @param verifier - Callable instance which will be invoked after all allocation cycle. Can be null;
  61      */
  62     public AllocationHelper(int maxIterations, int arrayLength, int chunkSize, Callable<?> verifier) {
  63         if ((arrayLength <= 0) || (maxIterations <= 0) || (chunkSize <= 0)) {
  64             throw new IllegalArgumentException("maxIterations, arrayLength and chunkSize should be greater then 0.");
  65         }
  66         this.arrayLength = arrayLength;
  67         this.maxIterations = maxIterations;
  68         this.chunkSize = chunkSize;
  69         verifierInstance = verifier;
  70         garbage = new byte[this.arrayLength][];
  71         garbageStorage = garbage;
  72     }
  73 
  74     private void allocateMemoryOneIteration() {
  75         for (int j = 0; j < arrayLength; j++) {
  76             garbage[j] = new byte[chunkSize];
  77         }
  78     }
  79 
  80     /**
  81      * Allocate memory and invoke Verifier during all iteration.
  82      *
  83      * @throws java.lang.Exception
  84      */
  85     public void allocateMemoryAndVerify() throws Exception {
  86         for (int i = 0; i < maxIterations; i++) {
  87             allocateMemoryOneIteration();
  88             if (verifierInstance != null) {
  89                 verifierInstance.call();
  90             }
  91         }
  92     }
  93 
  94     /**
  95      * The same as allocateMemoryAndVerify() but hides OOME
  96      *
  97      * @throws Exception
  98      */
  99     public void allocateMemoryAndVerifyNoOOME() throws Exception {
 100         try {
 101             allocateMemoryAndVerify();
 102         } catch (OutOfMemoryError e) {
 103             // exit on OOME
 104         }
 105     }
 106 
 107     /**
 108      * Release link to allocated garbage to make it available for further GC
 109      */
 110     public void release() {
 111         if (garbage != null) {
 112             garbage = null;
 113             garbageStorage = null;
 114         }
 115     }
 116 }