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