hotspot/test/serviceability/tmtools/jstat/utils/GcProvoker.java
changeset 43933 85ee551f3948
parent 42585 570f4b5312af
equal deleted inserted replaced
43433:acc1d9072823 43933:85ee551f3948
     1 /*
     1 /*
     2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2015, 2017, 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.
    20  * or visit www.oracle.com if you need additional information or have any
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    21  * questions.
    22  */
    22  */
    23 package utils;
    23 package utils;
    24 
    24 
    25 import java.lang.management.ManagementFactory;
       
    26 import java.lang.management.MemoryPoolMXBean;
       
    27 import java.lang.management.MemoryUsage;
       
    28 import java.util.ArrayList;
    25 import java.util.ArrayList;
    29 import java.util.List;
    26 import java.util.List;
    30 
    27 
    31 /**
    28 /**
    32  * This is an class used to provoke GC and perform other GC-related
    29  * This is an class used to provoke GC and perform other GC-related
    34  *
    31  *
    35  */
    32  */
    36 public class GcProvoker{
    33 public class GcProvoker{
    37 
    34 
    38     // Uses fixed small objects to avoid Humongous objects allocation in G1
    35     // Uses fixed small objects to avoid Humongous objects allocation in G1
    39     public static final int MEMORY_CHUNK = 2048;
    36     private static final int MEMORY_CHUNK = 2048;
    40     public static final float ALLOCATION_TOLERANCE = 0.05f;
       
    41 
       
    42     public static List<Object> allocatedMetaspace;
       
    43     public static List<Object> allocatedMemory;
       
    44 
    37 
    45     private final Runtime runtime;
    38     private final Runtime runtime;
    46 
    39 
    47     private List<Object> allocateHeap(float targetUsage) {
    40     private List<Object> allocateHeap(float targetUsage) {
    48         long maxMemory = runtime.maxMemory();
    41         long maxMemory = runtime.maxMemory();
    59             }
    52             }
    60         }
    53         }
    61         return list;
    54         return list;
    62     }
    55     }
    63 
    56 
    64     private List<Object> allocateAvailableHeap(float targetUsage) {
       
    65         // Calculates size of free memory after allocation with small tolerance.
       
    66         long minFreeMemory = (long) ((1.0 - (targetUsage + ALLOCATION_TOLERANCE)) * runtime.maxMemory());
       
    67         List<Object> list = new ArrayList<>();
       
    68         do {
       
    69             try {
       
    70                 list.add(new byte[MEMORY_CHUNK]);
       
    71             } catch (OutOfMemoryError e) {
       
    72                 list = null;
       
    73                 throw new RuntimeException("Unexpected OOME '" + e.getMessage() + "' while eating " + targetUsage + " of heap memory.");
       
    74             }
       
    75         } while (runtime.freeMemory() > minFreeMemory);
       
    76         return list;
       
    77     }
       
    78 
       
    79     /**
    57     /**
    80      * This method provokes a GC
    58      * This method provokes a GC
    81      */
    59      */
    82     public void provokeGc() {
    60     public void provokeGc() {
    83         for (int i = 0; i < 3; i++) {
    61         for (int i = 0; i < 3; i++) {
    91             allocateHeap(targetPercent);
    69             allocateHeap(targetPercent);
    92             System.gc();
    70             System.gc();
    93         }
    71         }
    94     }
    72     }
    95 
    73 
    96     /**
       
    97      * Allocates heap and metaspace upon exit not less than targetMemoryUsagePercent percents
       
    98      * of heap and metaspace have been consumed.
       
    99      *
       
   100      * @param targetMemoryUsagePercent how many percent of heap and metaspace to
       
   101      * allocate
       
   102      */
       
   103 
       
   104     public void allocateMetaspaceAndHeap(float targetMemoryUsagePercent) {
       
   105         // Metaspace should be filled before Java Heap to prevent unexpected OOME
       
   106         // in the Java Heap while filling Metaspace
       
   107         allocatedMetaspace = eatMetaspace(targetMemoryUsagePercent);
       
   108         allocatedMemory = allocateHeap(targetMemoryUsagePercent);
       
   109     }
       
   110 
       
   111     /**
       
   112      * Allocates heap and metaspace upon exit targetMemoryUsagePercent percents
       
   113      * of heap and metaspace have been consumed.
       
   114      *
       
   115      * @param targetMemoryUsagePercent how many percent of heap and metaspace to
       
   116      * allocate
       
   117      */
       
   118     public void allocateAvailableMetaspaceAndHeap(float targetMemoryUsagePercent) {
       
   119         // Metaspace should be filled before Java Heap to prevent unexpected OOME
       
   120         // in the Java Heap while filling Metaspace
       
   121         allocatedMetaspace = eatMetaspace(targetMemoryUsagePercent);
       
   122         allocatedMemory = allocateAvailableHeap(targetMemoryUsagePercent);
       
   123     }
       
   124 
       
   125     private List<Object> eatMetaspace(float targetUsage) {
       
   126         List<Object> list = new ArrayList<>();
       
   127         final String metaspacePoolName = "Metaspace";
       
   128         MemoryPoolMXBean metaspacePool = null;
       
   129         for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
       
   130             if (pool.getName().contains(metaspacePoolName)) {
       
   131                 metaspacePool = pool;
       
   132                 break;
       
   133             }
       
   134         }
       
   135         if (metaspacePool == null) {
       
   136             throw new RuntimeException("MXBean for Metaspace pool wasn't found");
       
   137         }
       
   138         float currentUsage;
       
   139         GeneratedClassProducer gp = new GeneratedClassProducer();
       
   140         do {
       
   141             try {
       
   142                 list.add(gp.create(0));
       
   143             } catch (OutOfMemoryError oome) {
       
   144                 list = null;
       
   145                 throw new RuntimeException("Unexpected OOME '" + oome.getMessage() + "' while eating " + targetUsage + " of Metaspace.");
       
   146             }
       
   147             MemoryUsage memoryUsage = metaspacePool.getUsage();
       
   148             currentUsage = (((float) memoryUsage.getUsed()) / memoryUsage.getMax());
       
   149         } while (currentUsage < targetUsage);
       
   150         return list;
       
   151     }
       
   152 
       
   153     public GcProvoker() {
    74     public GcProvoker() {
   154         runtime = Runtime.getRuntime();
    75         runtime = Runtime.getRuntime();
   155     }
    76     }
   156 
       
   157 }
    77 }