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 import java.lang.management.GarbageCollectorMXBean;
  25 import java.lang.management.ManagementFactory;
  26 import java.util.Arrays;
  27 import java.util.Objects;
  28 
  29 /**
  30  * Helper class with enum representation of GC types.
  31  */
  32 public final class GCTypes {
  33 
  34     private static <T extends GCType> T getCurrentGCType(Class<T> type) {
  35         return ManagementFactory.getGarbageCollectorMXBeans().stream()
  36                 .map(bean -> getGCTypeByName(type, bean.getName()))
  37                 .filter(Objects::nonNull)
  38                 .findFirst()
  39                 .orElse(null);
  40     }
  41 
  42     private static <T extends GCType> T getGCTypeByName(Class<T> type, String name) {
  43         return Arrays.stream(type.getEnumConstants())
  44                 .filter(e -> e.getGCName().equals(name))
  45                 .findFirst()
  46                 .orElse(null);
  47     }
  48 
  49     private static <T extends GCType> GarbageCollectorMXBean getGCBeanByType(Class<T> type) {
  50         return ManagementFactory.getGarbageCollectorMXBeans().stream()
  51                 .filter(bean -> Arrays.stream(type.getEnumConstants())
  52                         .filter(enumName -> enumName.getGCName().equals(bean.getName()))
  53                         .findFirst()
  54                         .isPresent()
  55                 )
  56                 .findFirst()
  57                 .orElse(null);
  58     }
  59 
  60     /**
  61      * Helper interface used by GCTypes static methods
  62      * to get gcTypeName field of *GCType classes.
  63      */
  64     private interface GCType {
  65 
  66         String getGCName();
  67     }
  68 
  69     public static enum YoungGCType implements GCType {
  70         DefNew("Copy"),
  71         ParNew("ParNew"),
  72         PSNew("PS Scavenge"),
  73         G1("G1 Young Generation");
  74 
  75         @Override
  76         public String getGCName() {
  77             return gcTypeName;
  78         }
  79         private final String gcTypeName;
  80 
  81         private YoungGCType(String name) {
  82             gcTypeName = name;
  83         }
  84 
  85         public static YoungGCType getYoungGCType() {
  86             return GCTypes.getCurrentGCType(YoungGCType.class);
  87         }
  88 
  89         public static GarbageCollectorMXBean getYoungGCBean() {
  90             return GCTypes.getGCBeanByType(YoungGCType.class);
  91         }
  92     }
  93 
  94     public static enum OldGCType implements GCType {
  95         Serial("MarkSweepCompact"),
  96         CMS("ConcurrentMarkSweep"),
  97         PSOld("PS MarkSweep"),
  98         G1("G1 Old Generation");
  99 
 100         private final String gcTypeName;
 101 
 102         private OldGCType(String name) {
 103             gcTypeName = name;
 104         }
 105 
 106         public static OldGCType getOldGCType() {
 107             return GCTypes.getCurrentGCType(OldGCType.class);
 108         }
 109 
 110         @Override
 111         public String getGCName() {
 112             return gcTypeName;
 113         }
 114     }
 115 }