1 /* 2 * Copyright (c) 2013, 2020, 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.metaspace; 25 26 import java.lang.management.GarbageCollectorMXBean; 27 import java.util.List; 28 import java.util.ArrayList; 29 30 import jdk.test.lib.ByteCodeLoader; 31 import jdk.test.lib.compiler.InMemoryJavaCompiler; 32 import jdk.test.lib.Platform; 33 34 import sun.management.ManagementFactoryHelper; 35 36 import static jdk.test.lib.Asserts.*; 37 import gc.testlibrary.PerfCounter; 38 import gc.testlibrary.PerfCounters; 39 40 /* @test TestMetaspacePerfCountersSerial 41 * @bug 8014659 42 * @requires vm.gc.Serial 43 * @library /test/lib / 44 * @summary Tests that performance counters for metaspace and compressed class 45 * space exists and works. 46 * @modules java.base/jdk.internal.misc 47 * java.compiler 48 * java.management/sun.management 49 * jdk.internal.jvmstat/sun.jvmstat.monitor 50 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC gc.metaspace.TestMetaspacePerfCounters 51 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC gc.metaspace.TestMetaspacePerfCounters 52 */ 53 54 /* @test TestMetaspacePerfCountersParallel 55 * @bug 8014659 56 * @requires vm.gc.Parallel 57 * @library /test/lib / 58 * @summary Tests that performance counters for metaspace and compressed class 59 * space exists and works. 60 * @modules java.base/jdk.internal.misc 61 * java.compiler 62 * java.management/sun.management 63 * jdk.internal.jvmstat/sun.jvmstat.monitor 64 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC gc.metaspace.TestMetaspacePerfCounters 65 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC gc.metaspace.TestMetaspacePerfCounters 66 */ 67 68 /* @test TestMetaspacePerfCountersG1 69 * @bug 8014659 70 * @requires vm.gc.G1 71 * @library /test/lib / 72 * @summary Tests that performance counters for metaspace and compressed class 73 * space exists and works. 74 * @modules java.base/jdk.internal.misc 75 * java.compiler 76 * java.management/sun.management 77 * jdk.internal.jvmstat/sun.jvmstat.monitor 78 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseG1GC gc.metaspace.TestMetaspacePerfCounters 79 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseG1GC gc.metaspace.TestMetaspacePerfCounters 80 */ 81 82 /* @test TestMetaspacePerfCountersShenandoah 83 * @bug 8014659 84 * @requires vm.gc.Shenandoah 85 * @library /test/lib / 86 * @summary Tests that performance counters for metaspace and compressed class 87 * space exists and works. 88 * @modules java.base/jdk.internal.misc 89 * java.compiler 90 * java.management/sun.management 91 * jdk.internal.jvmstat/sun.jvmstat.monitor 92 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC gc.metaspace.TestMetaspacePerfCounters 93 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC gc.metaspace.TestMetaspacePerfCounters 94 */ 95 public class TestMetaspacePerfCounters { 96 public static Class<?> fooClass = null; 97 private static final String[] counterNames = {"minCapacity", "maxCapacity", "capacity", "used"}; 98 private static final List<GarbageCollectorMXBean> gcBeans = ManagementFactoryHelper.getGarbageCollectorMXBeans(); 99 main(String[] args)100 public static void main(String[] args) throws Exception { 101 String metaspace = "sun.gc.metaspace"; 102 String ccs = "sun.gc.compressedclassspace"; 103 104 checkPerfCounters(metaspace); 105 106 if (isUsingCompressedClassPointers()) { 107 checkPerfCounters(ccs); 108 checkUsedIncreasesWhenLoadingClass(ccs); 109 } else { 110 checkEmptyPerfCounters(ccs); 111 checkUsedIncreasesWhenLoadingClass(metaspace); 112 } 113 } 114 checkPerfCounters(String ns)115 private static void checkPerfCounters(String ns) throws Exception { 116 long gcCountBefore; 117 long gcCountAfter; 118 long minCapacity; 119 long maxCapacity; 120 long capacity; 121 long used; 122 123 // The perf counter values are updated during GC and to be able to 124 // do the assertions below we need to ensure that the values are from 125 // the same GC cycle. 126 do { 127 gcCountBefore = currentGCCount(); 128 129 minCapacity = getMinCapacity(ns); 130 maxCapacity = getMaxCapacity(ns); 131 capacity = getCapacity(ns); 132 used = getUsed(ns); 133 134 gcCountAfter = currentGCCount(); 135 assertGTE(gcCountAfter, gcCountBefore); 136 } while(gcCountAfter > gcCountBefore); 137 138 assertGTE(minCapacity, 0L); 139 assertGTE(used, minCapacity); 140 assertGTE(capacity, used); 141 assertGTE(maxCapacity, capacity); 142 } 143 checkEmptyPerfCounters(String ns)144 private static void checkEmptyPerfCounters(String ns) throws Exception { 145 for (PerfCounter counter : countersInNamespace(ns)) { 146 String msg = "Expected " + counter.getName() + " to equal 0"; 147 assertEQ(counter.longValue(), 0L, msg); 148 } 149 } 150 checkUsedIncreasesWhenLoadingClass(String ns)151 private static void checkUsedIncreasesWhenLoadingClass(String ns) throws Exception { 152 // Need to ensure that used is up to date and that all unreachable 153 // classes are unloaded before doing this check. 154 System.gc(); 155 long before = getUsed(ns); 156 fooClass = compileAndLoad("Foo", "public class Foo { }"); 157 System.gc(); 158 long after = getUsed(ns); 159 160 assertGT(after, before); 161 } 162 countersInNamespace(String ns)163 private static List<PerfCounter> countersInNamespace(String ns) throws Exception { 164 List<PerfCounter> counters = new ArrayList<>(); 165 for (String name : counterNames) { 166 counters.add(PerfCounters.findByName(ns + "." + name)); 167 } 168 return counters; 169 } 170 compileAndLoad(String name, String source)171 private static Class<?> compileAndLoad(String name, String source) throws Exception { 172 byte[] byteCode = InMemoryJavaCompiler.compile(name, source); 173 return ByteCodeLoader.load(name, byteCode); 174 } 175 isUsingCompressedClassPointers()176 private static boolean isUsingCompressedClassPointers() { 177 return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedClassPointers"); 178 } 179 getMinCapacity(String ns)180 private static long getMinCapacity(String ns) throws Exception { 181 return PerfCounters.findByName(ns + ".minCapacity").longValue(); 182 } 183 getCapacity(String ns)184 private static long getCapacity(String ns) throws Exception { 185 return PerfCounters.findByName(ns + ".capacity").longValue(); 186 } 187 getMaxCapacity(String ns)188 private static long getMaxCapacity(String ns) throws Exception { 189 return PerfCounters.findByName(ns + ".maxCapacity").longValue(); 190 } 191 getUsed(String ns)192 private static long getUsed(String ns) throws Exception { 193 return PerfCounters.findByName(ns + ".used").longValue(); 194 } 195 currentGCCount()196 private static long currentGCCount() { 197 long gcCount = 0; 198 for (GarbageCollectorMXBean bean : gcBeans) { 199 gcCount += bean.getCollectionCount(); 200 } 201 return gcCount; 202 } 203 } 204