test/jdk/java/nio/Buffer/LimitDirectMemory.java
changeset 47216 71c04702a3d5
parent 45289 d56bca4fdf8f
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2002, 2017, 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  * @bug 4627316 6743526
       
    27  * @summary Test option to limit direct memory allocation
       
    28  * @requires (os.arch == "x86_64") | (os.arch == "amd64") | (os.arch == "sparcv9")
       
    29  * @library /test/lib
       
    30  *
       
    31  * @summary Test: memory is properly limited using multiple buffers
       
    32  * @run main/othervm -XX:MaxDirectMemorySize=10 LimitDirectMemory true 10 1
       
    33  * @run main/othervm -XX:MaxDirectMemorySize=1k LimitDirectMemory true 1k 100
       
    34  * @run main/othervm -XX:MaxDirectMemorySize=10m LimitDirectMemory true 10m 10m
       
    35  *
       
    36  * @summary Test: We can increase the amount of available memory
       
    37  * @run main/othervm -XX:MaxDirectMemorySize=65M LimitDirectMemory false 64M 65M
       
    38  *
       
    39  * @summary Test: Exactly the default amount of memory is available
       
    40  * @run main/othervm LimitDirectMemory false 10 1
       
    41  * @run main/othervm -Xmx64m LimitDirectMemory false 0 DEFAULT
       
    42  * @run main/othervm -Xmx64m LimitDirectMemory true 0 DEFAULT+1
       
    43  *
       
    44  * @summary Test: We should be able to eliminate direct memory allocation entirely
       
    45  * @run main/othervm -XX:MaxDirectMemorySize=0 LimitDirectMemory true 0 1
       
    46  *
       
    47  * @summary Test: Setting the system property should not work so we should be able
       
    48  *                to allocate the default amount
       
    49  * @run main/othervm -Dsun.nio.MaxDirectMemorySize=1K -Xmx64m
       
    50  *                   LimitDirectMemory false DEFAULT-1 DEFAULT/2
       
    51  */
       
    52 
       
    53 import java.nio.ByteBuffer;
       
    54 import java.util.Properties;
       
    55 
       
    56 public class LimitDirectMemory {
       
    57     private static final int K = 1024;
       
    58 
       
    59     public static void main(String [] args) throws Exception {
       
    60         if (args.length < 2) {
       
    61             throw new IllegalArgumentException("Usage: "
       
    62                     + "java LimitDirectMemory"
       
    63                     + " <OOME_expected(true|false)>"
       
    64                     + " <fill_direct_memory>"
       
    65                     + " <size_per_buffer>");
       
    66         }
       
    67         boolean throwp = parseThrow(args[0]);
       
    68         int size = parseSize(args[1]);
       
    69         int incr = (args.length > 2 ? parseSize(args[2]) : size);
       
    70 
       
    71         Properties p = System.getProperties();
       
    72         if (p.getProperty("sun.nio.MaxDirectMemorySize") != null)
       
    73             throw new RuntimeException("sun.nio.MaxDirectMemorySize defined");
       
    74 
       
    75         ByteBuffer [] b = new ByteBuffer[K];
       
    76 
       
    77         // Fill up most/all of the direct memory
       
    78         int i = 0;
       
    79         while (size >= incr) {
       
    80             b[i++] = ByteBuffer.allocateDirect(incr);
       
    81             size -= incr;
       
    82         }
       
    83 
       
    84         if (throwp) {
       
    85             try {
       
    86                 b[i] = ByteBuffer.allocateDirect(incr);
       
    87                 throw new RuntimeException("OutOfMemoryError not thrown: "
       
    88                                            + incr);
       
    89             } catch (OutOfMemoryError e) {
       
    90                 e.printStackTrace(System.out);
       
    91                 System.out.println("OK - Error thrown as expected ");
       
    92             }
       
    93         } else {
       
    94             b[i] = ByteBuffer.allocateDirect(incr);
       
    95             System.out.println("OK - Error not thrown");
       
    96         }
       
    97     }
       
    98 
       
    99     private static boolean parseThrow(String s) {
       
   100         if (s.equals("true"))  return true;
       
   101         if (s.equals("false")) return false;
       
   102         throw new RuntimeException("Unrecognized expectation: " + s);
       
   103     }
       
   104 
       
   105     private static int parseSize(String size) throws Exception {
       
   106 
       
   107         if (size.equals("DEFAULT"))
       
   108             return (int)Runtime.getRuntime().maxMemory();
       
   109         if (size.equals("DEFAULT+1"))
       
   110             return (int)Runtime.getRuntime().maxMemory() + 1;
       
   111         if (size.equals("DEFAULT+1M"))
       
   112             return (int)Runtime.getRuntime().maxMemory() + (1 << 20);
       
   113         if (size.equals("DEFAULT-1"))
       
   114             return (int)Runtime.getRuntime().maxMemory() - 1;
       
   115         if (size.equals("DEFAULT/2"))
       
   116             return (int)Runtime.getRuntime().maxMemory() / 2;
       
   117 
       
   118         int idx = 0, len = size.length();
       
   119 
       
   120 
       
   121         for (int i = 0; i < len; i++) {
       
   122             if (Character.isDigit(size.charAt(i))) idx++;
       
   123             else break;
       
   124         }
       
   125 
       
   126         if (idx == 0)
       
   127             throw new RuntimeException("No digits detected: " + size);
       
   128 
       
   129         int result = Integer.parseInt(size.substring(0, idx));
       
   130 
       
   131         if (idx < len) {
       
   132             for (int i = idx; i < len; i++) {
       
   133                 switch(size.charAt(i)) {
       
   134                 case 'T': case 't': result *= K; // fall through
       
   135                 case 'G': case 'g': result *= K; // fall through
       
   136                 case 'M': case 'm': result *= K; // fall through
       
   137                 case 'K': case 'k': result *= K;
       
   138                     break;
       
   139                 default:
       
   140                     throw new RuntimeException("Unrecognized size: " + size);
       
   141                 }
       
   142             }
       
   143         }
       
   144         return result;
       
   145     }
       
   146 }