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