1 /* 2 * Copyright (c) 2004, 2016, 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 /* 25 * @test 26 * @bug 5024531 27 * @summary Test type mapping of the platform MXBean proxy 28 * returned from Management.newPlatformMXBeanProxy(). 29 * @author Mandy Chung 30 * 31 * @compile ProxyTypeMapping.java 32 * @run main/othervm -verbose:gc ProxyTypeMapping 33 */ 34 import java.lang.management.*; 35 import javax.management.*; 36 import static java.lang.management.ManagementFactory.*; 37 import java.util.List; 38 import java.util.Map; 39 import com.sun.management.GcInfo; 40 41 public class ProxyTypeMapping { 42 private static MBeanServer server = 43 ManagementFactory.getPlatformMBeanServer(); 44 private static RuntimeMXBean runtime; 45 private static ThreadMXBean thread; 46 private static MemoryMXBean memory; 47 private static MemoryPoolMXBean heapPool = null; 48 private static MemoryPoolMXBean nonHeapPool = null; 49 public static void main(String[] argv) throws Exception { 50 runtime = newPlatformMXBeanProxy(server, 51 RUNTIME_MXBEAN_NAME, 52 RuntimeMXBean.class); 53 thread = newPlatformMXBeanProxy(server, 54 THREAD_MXBEAN_NAME, 55 ThreadMXBean.class); 56 memory = newPlatformMXBeanProxy(server, 57 MEMORY_MXBEAN_NAME, 58 MemoryMXBean.class); 59 60 // check notification emitter 61 MyListener listener = new MyListener(); 62 NotificationEmitter emitter = (NotificationEmitter) memory; 63 emitter.addNotificationListener(listener, null, null); 64 emitter.removeNotificationListener(listener); 65 66 List<MemoryPoolMXBean> pools = getMemoryPoolMXBeans(); 67 for (MemoryPoolMXBean p : pools) { 68 if (heapPool == null && 69 p.getType() == MemoryType.HEAP && 70 p.isUsageThresholdSupported() && 71 p.isCollectionUsageThresholdSupported()) { 72 heapPool = p; 73 } 74 if (nonHeapPool == null && 75 p.getType() == MemoryType.NON_HEAP && 76 p.isUsageThresholdSupported()) { 77 nonHeapPool = p; 78 } 79 } 80 81 checkEnum(); 82 checkList(); 83 checkMap(); 84 checkMemoryUsage(); 85 checkThreadInfo(); 86 87 checkOS(); 88 checkSunGC(); 89 90 System.out.println("Test passed."); 91 } 92 93 private static void checkEnum() throws Exception { 94 MemoryType type = heapPool.getType(); 95 if (type != MemoryType.HEAP) { 96 throw new RuntimeException("TEST FAILED: " + 97 " incorrect memory type for " + heapPool.getName()); 98 } 99 100 type = nonHeapPool.getType(); 101 if (type != MemoryType.NON_HEAP) { 102 throw new RuntimeException("TEST FAILED: " + 103 " incorrect memory type for " + nonHeapPool.getName()); 104 } 105 } 106 107 private static final String OPTION = "-verbose:gc"; 108 private static void checkList() throws Exception { 109 List<String> args = runtime.getInputArguments(); 110 if (args.size() < 1) { 111 throw new RuntimeException("TEST FAILED: " + 112 " empty input arguments"); 113 } 114 // check if -verbose:gc exists 115 boolean found = false; 116 for (String option : args) { 117 if (option.equals(OPTION)) { 118 found = true; 119 break; 120 } 121 } 122 if (!found) { 123 throw new RuntimeException("TEST FAILED: " + 124 "VM option " + OPTION + " not found"); 125 } 126 } 127 128 private static final String KEY1 = "test.property.key1"; 129 private static final String VALUE1 = "test.property.value1"; 130 private static final String KEY2 = "test.property.key2"; 131 private static final String VALUE2 = "test.property.value2"; 132 private static final String KEY3 = "test.property.key3"; 133 private static void checkMap() throws Exception { 134 // Add new system properties 135 System.setProperty(KEY1, VALUE1); 136 System.setProperty(KEY2, VALUE2); 137 138 Map<String,String> props1 = runtime.getSystemProperties(); 139 String value1 = props1.get(KEY1); 140 if (value1 == null || !value1.equals(VALUE1)) { 141 throw new RuntimeException("TEST FAILED: " + 142 KEY1 + " property found" + 143 " with value = " + value1 + 144 " but expected to be " + VALUE1); 145 } 146 147 String value2 = props1.get(KEY2); 148 if (value2 == null || !value2.equals(VALUE2)) { 149 throw new RuntimeException("TEST FAILED: " + 150 KEY2 + " property found" + 151 " with value = " + value2 + 152 " but expected to be " + VALUE2); 153 } 154 155 String value3 = props1.get(KEY3); 156 if (value3 != null) { 157 throw new RuntimeException("TEST FAILED: " + 158 KEY3 + " property found" + 159 " but should not exist" ); 160 } 161 } 162 163 private static void checkMemoryUsage() throws Exception { 164 // sanity check to have non-negative usage 165 MemoryUsage u1 = memory.getHeapMemoryUsage(); 166 MemoryUsage u2 = memory.getNonHeapMemoryUsage(); 167 MemoryUsage u3 = heapPool.getUsage(); 168 MemoryUsage u4 = nonHeapPool.getUsage(); 169 if (u1.getCommitted() < 0 || 170 u2.getCommitted() < 0 || 171 u3.getCommitted() < 0 || 172 u4.getCommitted() < 0) { 173 throw new RuntimeException("TEST FAILED: " + 174 " expected non-negative committed usage"); 175 } 176 memory.gc(); 177 MemoryUsage u5 = heapPool.getCollectionUsage(); 178 if (u5.getCommitted() < 0) { 179 throw new RuntimeException("TEST FAILED: " + 180 " expected non-negative committed collected usage"); 181 } 182 } 183 184 private static void checkThreadInfo() throws Exception { 185 // assume all threads stay alive 186 long[] ids = thread.getAllThreadIds(); 187 ThreadInfo[] infos = thread.getThreadInfo(ids); 188 for (ThreadInfo ti : infos) { 189 printThreadInfo(ti); 190 } 191 infos = thread.getThreadInfo(ids, 2); 192 for (ThreadInfo ti : infos) { 193 printThreadInfo(ti); 194 } 195 long id = Thread.currentThread().getId(); 196 ThreadInfo info = thread.getThreadInfo(id); 197 printThreadInfo(info); 198 info = thread.getThreadInfo(id, 2); 199 printThreadInfo(info); 200 } 201 202 private static void printThreadInfo(ThreadInfo info) { 203 if (info == null) { 204 throw new RuntimeException("TEST FAILED: " + 205 " Null ThreadInfo"); 206 } 207 208 System.out.print(info.getThreadName()); 209 System.out.print(" id=" + info.getThreadId()); 210 System.out.println(" " + info.getThreadState()); 211 212 for (StackTraceElement s : info.getStackTrace()) { 213 System.out.println(s); 214 } 215 } 216 217 private static void checkOS() throws Exception { 218 com.sun.management.OperatingSystemMXBean os = 219 newPlatformMXBeanProxy(server, 220 OPERATING_SYSTEM_MXBEAN_NAME, 221 com.sun.management.OperatingSystemMXBean.class); 222 System.out.println("# CPUs = " + os.getAvailableProcessors()); 223 System.out.println("Committed virtual memory = " + 224 os.getCommittedVirtualMemorySize()); 225 } 226 227 private static void checkSunGC() throws Exception { 228 // Test com.sun.management proxy 229 List<GarbageCollectorMXBean> gcs = getGarbageCollectorMXBeans(); 230 for (GarbageCollectorMXBean gc : gcs) { 231 com.sun.management.GarbageCollectorMXBean sunGc = 232 newPlatformMXBeanProxy(server, 233 GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=" + gc.getName(), 234 com.sun.management.GarbageCollectorMXBean.class); 235 GcInfo info = sunGc.getLastGcInfo(); 236 if (info != null) { 237 System.out.println("GC statistic for : " + gc.getName()); 238 printGcInfo(info); 239 } 240 } 241 } 242 private static void printGcInfo(GcInfo info) throws Exception { 243 System.out.print("GC #" + info.getId()); 244 System.out.print(" start:" + info.getStartTime()); 245 System.out.print(" end:" + info.getEndTime()); 246 System.out.println(" (" + info.getDuration() + "ms)"); 247 Map<String,MemoryUsage> usage = info.getMemoryUsageBeforeGc(); 248 249 for (Map.Entry<String,MemoryUsage> entry : usage.entrySet()) { 250 String poolname = entry.getKey(); 251 MemoryUsage busage = entry.getValue(); 252 MemoryUsage ausage = info.getMemoryUsageAfterGc().get(poolname); 253 if (ausage == null) { 254 throw new RuntimeException("After Gc Memory does not exist" + 255 " for " + poolname); 256 } 257 System.out.println("Usage for pool " + poolname); 258 System.out.println(" Before GC: " + busage); 259 System.out.println(" After GC: " + ausage); 260 } 261 } 262 263 static class MyListener implements NotificationListener { 264 public void handleNotification(Notification notif, Object handback) { 265 return; 266 } 267 } 268 }