test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 49934 44839fbb20db
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
     1 /*
     1 /*
     2  * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    24 package nsk.share.gc.gp;
    24 package nsk.share.gc.gp;
    25 
    25 
    26 import java.io.IOException;
    26 import java.io.IOException;
    27 import java.io.PrintWriter;
    27 import java.io.PrintWriter;
    28 import java.io.StringWriter;
    28 import java.io.StringWriter;
       
    29 import java.lang.invoke.*;
    29 import java.util.*;
    30 import java.util.*;
    30 import nsk.share.gc.gp.array.*;
    31 import nsk.share.gc.gp.array.*;
    31 import nsk.share.gc.gp.string.*;
    32 import nsk.share.gc.gp.string.*;
    32 import nsk.share.gc.gp.list.*;
    33 import nsk.share.gc.gp.list.*;
    33 import nsk.share.gc.gp.tree.*;
    34 import nsk.share.gc.gp.tree.*;
    55             OOM_TYPE(String... expectedStrings) {
    56             OOM_TYPE(String... expectedStrings) {
    56                 this.expectedStrings = expectedStrings;
    57                 this.expectedStrings = expectedStrings;
    57             }
    58             }
    58 
    59 
    59             /**
    60             /**
    60                          * Returns true if the given error message matches
    61              * Returns true if the given error message matches
    61                          * one of expected strings.
    62              * one of expected strings.
    62                          */
    63              */
    63                         public boolean accept(String errorMessage) {
    64             public boolean accept(String errorMessage) {
    64                 if (expectedStrings == null || expectedStrings.length == 0 || errorMessage == null) {
    65                 if (expectedStrings == null || expectedStrings.length == 0 || errorMessage == null) {
    65                     return true;
    66                     return true;
    66                 }
    67                 }
    67                 for (String s: expectedStrings) {
    68                 for (String s: expectedStrings) {
    68                     if (errorMessage.indexOf(s) != -1) {
    69                     if (errorMessage.indexOf(s) != -1) {
    71                 }
    72                 }
    72                 return false;
    73                 return false;
    73             }
    74             }
    74         };
    75         };
    75 
    76 
    76         // Force loading of OOM_TYPE and calling of enum contrusctors when loading GarbageUtils class.
    77         // Force loading of OOM_TYPE and calling of enum constructors when loading GarbageUtils class.
    77         public static final Object[] thisIsGarbageArray_theOnlyPurposeForCreatingItAndDeclaringItPublicIsToInitializeIntancesOfOOMEnumberation = new Object[] { OOM_TYPE.ANY, OOM_TYPE.HEAP, OOM_TYPE.METASPACE };
    78         public static final Object[] thisIsGarbageArray_theOnlyPurposeForCreatingItAndDeclaringItPublicIsToInitializeIntancesOfOOMEnumberation = new Object[] { OOM_TYPE.ANY, OOM_TYPE.HEAP, OOM_TYPE.METASPACE };
    78 
    79 
    79         // Force early loading of classes that might otherwise unexpectedly fail
    80         // Force early loading of classes that might otherwise unexpectedly fail
    80         // class loading during testing due to high memory pressure.
    81         // class loading during testing due to high memory pressure.
    81         public static final StringWriter preloadStringWriter = new StringWriter(1);
    82         public static final StringWriter preloadStringWriter = new StringWriter(1);
    82         public static final PrintWriter preloadPrintWriter = new PrintWriter(preloadStringWriter);
    83         public static final PrintWriter preloadPrintWriter = new PrintWriter(preloadStringWriter);
       
    84         public static final Throwable preloadThrowable = new Throwable("preload");
    83 
    85 
    84         private GarbageUtils() {
    86         private GarbageUtils() {
    85         }
    87         }
    86 
    88 
    87         /**
    89         /**
   191          */
   193          */
   192         public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor) {
   194         public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor) {
   193             return eatMemory(stresser, gp, initialFactor, minMemoryChunk, factor, OOM_TYPE.ANY);
   195             return eatMemory(stresser, gp, initialFactor, minMemoryChunk, factor, OOM_TYPE.ANY);
   194         }
   196         }
   195 
   197 
       
   198          static int numberOfOOMEs = 0;
       
   199 
       
   200          /**
       
   201           * Minimal wrapper of the main implementation. Catches any OOM
       
   202           * that might be thrown when rematerializing Objects when deoptimizing.
       
   203           *
       
   204           * It is Important that the impl is not inlined.
       
   205           */
       
   206 
       
   207          public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) {
       
   208             try {
       
   209                // Using a methodhandle invoke of eatMemoryImpl to prevent inlining of it
       
   210                MethodHandles.Lookup lookup = MethodHandles.lookup();
       
   211                MethodType mt = MethodType.methodType(
       
   212                      int.class,
       
   213                      ExecutionController.class,
       
   214                      GarbageProducer.class,
       
   215                      long.class,
       
   216                      long.class,
       
   217                      long.class,
       
   218                      OOM_TYPE.class);
       
   219                MethodHandle eat = lookup.findStatic(GarbageUtils.class, "eatMemoryImpl", mt);
       
   220                return (int) eat.invoke(stresser, gp, initialFactor, minMemoryChunk, factor, type);
       
   221             } catch (OutOfMemoryError e) {
       
   222                return numberOfOOMEs++;
       
   223             } catch (Throwable t) {
       
   224                throw new RuntimeException(t);
       
   225             }
       
   226          }
       
   227 
   196         /**
   228         /**
   197          * Eat memory using given garbage producer.
   229          * Eat memory using given garbage producer.
   198          *
   230          *
   199          * Note that this method can throw Failure if any exception
   231          * Note that this method can throw Failure if any exception
   200          * is thrown while eating memory. To avoid OOM while allocating
   232          * is thrown while eating memory. To avoid OOM while allocating
   208          * @param minMemoryChunk determines when to stop
   240          * @param minMemoryChunk determines when to stop
   209          * @param factor factor to divide the array size by. A value of 0 means that method returns after first  OOME
   241          * @param factor factor to divide the array size by. A value of 0 means that method returns after first  OOME
   210          * @param type of OutOfMemory Exception: Java heap space or Metadata space
   242          * @param type of OutOfMemory Exception: Java heap space or Metadata space
   211          * @return number of OOME occured
   243          * @return number of OOME occured
   212          */
   244          */
   213         public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) {
   245 
   214                 int numberOfOOMEs = 0;
   246          public static int eatMemoryImpl(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) {
       
   247                 numberOfOOMEs = 0;
   215                 try {
   248                 try {
   216                         StringWriter sw = new StringWriter(10000);
       
   217                         PrintWriter pw = new PrintWriter(sw);
       
   218                         byte[] someMemory = new byte[200000]; //200 Kb
   249                         byte[] someMemory = new byte[200000]; //200 Kb
   219                         try {
   250                         try {
   220                                 Runtime runtime = Runtime.getRuntime();
   251                                 Runtime runtime = Runtime.getRuntime();
   221                                 long maxMemory = runtime.maxMemory();
   252                                 long maxMemory = runtime.maxMemory();
   222                                 long maxMemoryChunk = maxMemory / initialFactor;
   253                                 long maxMemoryChunk = maxMemory / initialFactor;
   239                                                     allocations = 0;
   270                                                     allocations = 0;
   240                                                 }
   271                                                 }
   241                                         } catch (OutOfMemoryError e) {
   272                                         } catch (OutOfMemoryError e) {
   242                                             someMemory = null;
   273                                             someMemory = null;
   243                                             if (type != OOM_TYPE.ANY) {
   274                                             if (type != OOM_TYPE.ANY) {
   244                                                 e.printStackTrace(pw);
   275                                                 if (type.accept(e.toString())) {
   245                                                 pw.close();
       
   246                                                 if (type.accept(sw.toString())) {
       
   247                                                     numberOfOOMEs++;
   276                                                     numberOfOOMEs++;
   248                                                 } else {
   277                                                 } else {
   249                                                     // Trying to catch situation when Java generates OOM different type that test trying to catch
   278                                                     // Trying to catch situation when Java generates OOM different type that test trying to catch
   250                                                     throw new TestBug("Test throw OOM of unexpected type." + sw.toString());
   279                                                     throw new TestBug("Test throw OOM of unexpected type." + e.toString());
   251                                                 }
   280                                                 }
   252                                             } else {
   281                                             } else {
   253                                                numberOfOOMEs++;
   282                                                numberOfOOMEs++;
   254                                             }
   283                                             }
   255                                             allocations = 0;
   284                                             allocations = 0;
   261                                         }
   290                                         }
   262                                 }
   291                                 }
   263                         } catch (OutOfMemoryError e) {
   292                         } catch (OutOfMemoryError e) {
   264                             someMemory = null;
   293                             someMemory = null;
   265                             if (type != OOM_TYPE.ANY) {
   294                             if (type != OOM_TYPE.ANY) {
   266                                 e.printStackTrace(pw);
   295                                 if (type.accept(e.toString())) {
   267                                 pw.close();
       
   268                                 if (type.accept(sw.toString())) {
       
   269                                     numberOfOOMEs++;
   296                                     numberOfOOMEs++;
   270                                 } else {
   297                                 } else {
   271                                     // Trying to catch situation when Java generates OOM different type that test trying to catch
   298                                     // Trying to catch situation when Java generates OOM different type that test trying to catch
   272                                     throw new TestBug("Test throw OOM of unexpected type." + sw.toString());
   299                                     throw new TestBug("Test throw OOM of unexpected type." + e.toString());
   273                                 }
   300                                 }
   274                             } else {
   301                             } else {
   275                                 numberOfOOMEs++;
   302                                 numberOfOOMEs++;
   276                             }
   303                             }
   277                          // all memory is eaten now even before we start, just return
   304                          // all memory is eaten now even before we start, just return