1 /* 2 * Copyright (c) 2003, 2012, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.management; 27 28 import java.lang.management.*; 29 30 import javax.management.InstanceAlreadyExistsException; 31 import javax.management.InstanceNotFoundException; 32 import javax.management.MBeanServer; 33 import javax.management.MBeanRegistrationException; 34 import javax.management.NotCompliantMBeanException; 35 import javax.management.ObjectName; 36 import javax.management.RuntimeOperationsException; 37 import java.security.AccessController; 38 import java.security.PrivilegedActionException; 39 import java.security.PrivilegedExceptionAction; 40 41 import sun.util.logging.LoggingSupport; 42 43 import java.util.ArrayList; 44 import java.util.Collections; 45 import java.util.List; 46 import com.sun.management.DiagnosticCommandMBean; 47 import com.sun.management.OSMBeanFactory; 48 import com.sun.management.HotSpotDiagnosticMXBean; 49 50 import static java.lang.management.ManagementFactory.*; 51 52 /** 53 * ManagementFactoryHelper provides static factory methods to create 54 * instances of the management interface. 55 */ 56 public class ManagementFactoryHelper { 57 private ManagementFactoryHelper() {}; 58 59 private static VMManagement jvm; 60 61 private static ClassLoadingImpl classMBean = null; 62 private static MemoryImpl memoryMBean = null; 63 private static ThreadImpl threadMBean = null; 64 private static RuntimeImpl runtimeMBean = null; 65 private static CompilationImpl compileMBean = null; 66 private static OperatingSystemImpl osMBean = null; 67 68 public static synchronized ClassLoadingMXBean getClassLoadingMXBean() { 69 if (classMBean == null) { 70 classMBean = new ClassLoadingImpl(jvm); 71 } 72 return classMBean; 73 } 74 75 public static synchronized MemoryMXBean getMemoryMXBean() { 76 if (memoryMBean == null) { 77 memoryMBean = new MemoryImpl(jvm); 78 } 79 return memoryMBean; 80 } 81 82 public static synchronized ThreadMXBean getThreadMXBean() { 83 if (threadMBean == null) { 84 threadMBean = new ThreadImpl(jvm); 85 } 86 return threadMBean; 87 } 88 89 public static synchronized RuntimeMXBean getRuntimeMXBean() { 90 if (runtimeMBean == null) { 91 runtimeMBean = new RuntimeImpl(jvm); 92 } 93 return runtimeMBean; 94 } 95 96 public static synchronized CompilationMXBean getCompilationMXBean() { 97 if (compileMBean == null && jvm.getCompilerName() != null) { 98 compileMBean = new CompilationImpl(jvm); 99 } 100 return compileMBean; 101 } 102 103 public static synchronized OperatingSystemMXBean getOperatingSystemMXBean() { 104 if (osMBean == null) { 105 osMBean = (OperatingSystemImpl) 106 OSMBeanFactory.getOperatingSystemMXBean(jvm); 107 } 108 return osMBean; 109 } 110 111 public static List<MemoryPoolMXBean> getMemoryPoolMXBeans() { 112 MemoryPoolMXBean[] pools = MemoryImpl.getMemoryPools(); 113 List<MemoryPoolMXBean> list = new ArrayList<>(pools.length); 114 for (MemoryPoolMXBean p : pools) { 115 list.add(p); 116 } 117 return list; 118 } 119 120 public static List<MemoryManagerMXBean> getMemoryManagerMXBeans() { 121 MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers(); 122 List<MemoryManagerMXBean> result = new ArrayList<>(mgrs.length); 123 for (MemoryManagerMXBean m : mgrs) { 124 result.add(m); 125 } 126 return result; 127 } 128 129 public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans() { 130 MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers(); 131 List<GarbageCollectorMXBean> result = new ArrayList<>(mgrs.length); 132 for (MemoryManagerMXBean m : mgrs) { 133 if (GarbageCollectorMXBean.class.isInstance(m)) { 134 result.add(GarbageCollectorMXBean.class.cast(m)); 135 } 136 } 137 return result; 138 } 139 140 public static PlatformLoggingMXBean getPlatformLoggingMXBean() { 141 if (LoggingSupport.isAvailable()) { 142 return PlatformLoggingImpl.instance; 143 } else { 144 return null; 145 } 146 } 147 148 // The logging MXBean object is an instance of 149 // PlatformLoggingMXBean and java.util.logging.LoggingMXBean 150 // but it can't directly implement two MXBean interfaces 151 // as a compliant MXBean implements exactly one MXBean interface, 152 // or if it implements one interface that is a subinterface of 153 // all the others; otherwise, it is a non-compliant MXBean 154 // and MBeanServer will throw NotCompliantMBeanException. 155 // See the Definition of an MXBean section in javax.management.MXBean spec. 156 // 157 // To create a compliant logging MXBean, define a LoggingMXBean interface 158 // that extend PlatformLoggingMXBean and j.u.l.LoggingMXBean 159 interface LoggingMXBean 160 extends PlatformLoggingMXBean, java.util.logging.LoggingMXBean { 161 } 162 163 static class PlatformLoggingImpl implements LoggingMXBean 164 { 165 final static PlatformLoggingMXBean instance = new PlatformLoggingImpl(); 166 final static String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"; 167 168 private volatile ObjectName objname; // created lazily 169 @Override 170 public ObjectName getObjectName() { 171 ObjectName result = objname; 172 if (result == null) { 173 synchronized (this) { 174 result = objname; 175 if (result == null) { 176 result = Util.newObjectName(LOGGING_MXBEAN_NAME); 177 objname = result; 178 } 179 } 180 } 181 return result; 182 } 183 184 @Override 185 public java.util.List<String> getLoggerNames() { 186 return LoggingSupport.getLoggerNames(); 187 } 188 189 @Override 190 public String getLoggerLevel(String loggerName) { 191 return LoggingSupport.getLoggerLevel(loggerName); 192 } 193 194 @Override 195 public void setLoggerLevel(String loggerName, String levelName) { 196 LoggingSupport.setLoggerLevel(loggerName, levelName); 197 } 198 199 @Override 200 public String getParentLoggerName(String loggerName) { 201 return LoggingSupport.getParentLoggerName(loggerName); 202 } 203 } 204 205 private static List<BufferPoolMXBean> bufferPools = null; 206 public static synchronized List<BufferPoolMXBean> getBufferPoolMXBeans() { 207 if (bufferPools == null) { 208 bufferPools = new ArrayList<>(2); 209 bufferPools.add(createBufferPoolMXBean(sun.misc.SharedSecrets.getJavaNioAccess() 210 .getDirectBufferPool())); 211 bufferPools.add(createBufferPoolMXBean(sun.nio.ch.FileChannelImpl 212 .getMappedBufferPool())); 213 } 214 return bufferPools; 215 } 216 217 private final static String BUFFER_POOL_MXBEAN_NAME = "java.nio:type=BufferPool"; 218 219 /** 220 * Creates management interface for the given buffer pool. 221 */ 222 private static BufferPoolMXBean 223 createBufferPoolMXBean(final sun.misc.JavaNioAccess.BufferPool pool) 224 { 225 return new BufferPoolMXBean() { 226 private volatile ObjectName objname; // created lazily 227 @Override 228 public ObjectName getObjectName() { 229 ObjectName result = objname; 230 if (result == null) { 231 synchronized (this) { 232 result = objname; 233 if (result == null) { 234 result = Util.newObjectName(BUFFER_POOL_MXBEAN_NAME + 235 ",name=" + pool.getName()); 236 objname = result; 237 } 238 } 239 } 240 return result; 241 } 242 @Override 243 public String getName() { 244 return pool.getName(); 245 } 246 @Override 247 public long getCount() { 248 return pool.getCount(); 249 } 250 @Override 251 public long getTotalCapacity() { 252 return pool.getTotalCapacity(); 253 } 254 @Override 255 public long getMemoryUsed() { 256 return pool.getMemoryUsed(); 257 } 258 }; 259 } 260 261 private static HotSpotDiagnostic hsDiagMBean = null; 262 private static HotspotRuntime hsRuntimeMBean = null; 263 private static HotspotClassLoading hsClassMBean = null; 264 private static HotspotThread hsThreadMBean = null; 265 private static HotspotCompilation hsCompileMBean = null; 266 private static HotspotMemory hsMemoryMBean = null; 267 private static DiagnosticCommandImpl hsDiagCommandMBean = null; 268 269 public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() { 270 if (hsDiagMBean == null) { 271 hsDiagMBean = new HotSpotDiagnostic(); 272 } 273 return hsDiagMBean; 274 } 275 276 /** 277 * This method is for testing only. 278 */ 279 public static synchronized HotspotRuntimeMBean getHotspotRuntimeMBean() { 280 if (hsRuntimeMBean == null) { 281 hsRuntimeMBean = new HotspotRuntime(jvm); 282 } 283 return hsRuntimeMBean; 284 } 285 286 /** 287 * This method is for testing only. 288 */ 289 public static synchronized HotspotClassLoadingMBean getHotspotClassLoadingMBean() { 290 if (hsClassMBean == null) { 291 hsClassMBean = new HotspotClassLoading(jvm); 292 } 293 return hsClassMBean; 294 } 295 296 /** 297 * This method is for testing only. 298 */ 299 public static synchronized HotspotThreadMBean getHotspotThreadMBean() { 300 if (hsThreadMBean == null) { 301 hsThreadMBean = new HotspotThread(jvm); 302 } 303 return hsThreadMBean; 304 } 305 306 /** 307 * This method is for testing only. 308 */ 309 public static synchronized HotspotMemoryMBean getHotspotMemoryMBean() { 310 if (hsMemoryMBean == null) { 311 hsMemoryMBean = new HotspotMemory(jvm); 312 } 313 return hsMemoryMBean; 314 } 315 316 public static synchronized DiagnosticCommandMBean getDiagnosticCommandMBean() { 317 // Remote Diagnostic Commands may not be supported 318 if (hsDiagCommandMBean == null && jvm.isRemoteDiagnosticCommandsSupported()) { 319 hsDiagCommandMBean = new DiagnosticCommandImpl(jvm); 320 } 321 return hsDiagCommandMBean; 322 } 323 324 /** 325 * This method is for testing only. 326 */ 327 public static synchronized HotspotCompilationMBean getHotspotCompilationMBean() { 328 if (hsCompileMBean == null) { 329 hsCompileMBean = new HotspotCompilation(jvm); 330 } 331 return hsCompileMBean; 332 } 333 334 /** 335 * Registers a given MBean if not registered in the MBeanServer; 336 * otherwise, just return. 337 */ 338 private static void addMBean(MBeanServer mbs, Object mbean, String mbeanName) { 339 try { 340 final ObjectName objName = Util.newObjectName(mbeanName); 341 342 // inner class requires these fields to be final 343 final MBeanServer mbs0 = mbs; 344 final Object mbean0 = mbean; 345 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { 346 public Void run() throws MBeanRegistrationException, 347 NotCompliantMBeanException { 348 try { 349 mbs0.registerMBean(mbean0, objName); 350 return null; 351 } catch (InstanceAlreadyExistsException e) { 352 // if an instance with the object name exists in 353 // the MBeanServer ignore the exception 354 } 355 return null; 356 } 357 }); 358 } catch (PrivilegedActionException e) { 359 throw Util.newException(e.getException()); 360 } 361 } 362 363 private final static String HOTSPOT_CLASS_LOADING_MBEAN_NAME = 364 "sun.management:type=HotspotClassLoading"; 365 366 private final static String HOTSPOT_COMPILATION_MBEAN_NAME = 367 "sun.management:type=HotspotCompilation"; 368 369 private final static String HOTSPOT_MEMORY_MBEAN_NAME = 370 "sun.management:type=HotspotMemory"; 371 372 private static final String HOTSPOT_RUNTIME_MBEAN_NAME = 373 "sun.management:type=HotspotRuntime"; 374 375 private final static String HOTSPOT_THREAD_MBEAN_NAME = 376 "sun.management:type=HotspotThreading"; 377 378 public static List<PlatformManagedObject> getPlatformDynamicMBeans() { 379 List<PlatformManagedObject> list = new ArrayList<>(); 380 if(getDiagnosticCommandMBean() != null) { 381 list.add(getDiagnosticCommandMBean()); 382 } 383 return list; 384 } 385 386 static void registerInternalMBeans(MBeanServer mbs) { 387 // register all internal MBeans if not registered 388 // No exception is thrown if a MBean with that object name 389 // already registered 390 addMBean(mbs, getHotspotClassLoadingMBean(), 391 HOTSPOT_CLASS_LOADING_MBEAN_NAME); 392 addMBean(mbs, getHotspotMemoryMBean(), 393 HOTSPOT_MEMORY_MBEAN_NAME); 394 addMBean(mbs, getHotspotRuntimeMBean(), 395 HOTSPOT_RUNTIME_MBEAN_NAME); 396 addMBean(mbs, getHotspotThreadMBean(), 397 HOTSPOT_THREAD_MBEAN_NAME); 398 399 // CompilationMBean may not exist 400 if (getCompilationMXBean() != null) { 401 addMBean(mbs, getHotspotCompilationMBean(), 402 HOTSPOT_COMPILATION_MBEAN_NAME); 403 } 404 } 405 406 private static void unregisterMBean(MBeanServer mbs, String mbeanName) { 407 try { 408 final ObjectName objName = Util.newObjectName(mbeanName); 409 410 // inner class requires these fields to be final 411 final MBeanServer mbs0 = mbs; 412 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { 413 public Void run() throws MBeanRegistrationException, 414 RuntimeOperationsException { 415 try { 416 mbs0.unregisterMBean(objName); 417 } catch (InstanceNotFoundException e) { 418 // ignore exception if not found 419 } 420 return null; 421 } 422 }); 423 } catch (PrivilegedActionException e) { 424 throw Util.newException(e.getException()); 425 } 426 } 427 428 static void unregisterInternalMBeans(MBeanServer mbs) { 429 // unregister all internal MBeans 430 unregisterMBean(mbs, HOTSPOT_CLASS_LOADING_MBEAN_NAME); 431 unregisterMBean(mbs, HOTSPOT_MEMORY_MBEAN_NAME); 432 unregisterMBean(mbs, HOTSPOT_RUNTIME_MBEAN_NAME); 433 unregisterMBean(mbs, HOTSPOT_THREAD_MBEAN_NAME); 434 435 // CompilationMBean may not exist 436 if (getCompilationMXBean() != null) { 437 unregisterMBean(mbs, HOTSPOT_COMPILATION_MBEAN_NAME); 438 } 439 } 440 441 static { 442 AccessController.doPrivileged( 443 new java.security.PrivilegedAction<Void>() { 444 public Void run() { 445 System.loadLibrary("management"); 446 return null; 447 } 448 }); 449 jvm = new VMManagementImpl(); 450 } 451 452 public static boolean isThreadSuspended(int state) { 453 return ((state & JMM_THREAD_STATE_FLAG_SUSPENDED) != 0); 454 } 455 456 public static boolean isThreadRunningNative(int state) { 457 return ((state & JMM_THREAD_STATE_FLAG_NATIVE) != 0); 458 } 459 460 public static Thread.State toThreadState(int state) { 461 // suspended and native bits may be set in state 462 int threadStatus = state & ~JMM_THREAD_STATE_FLAG_MASK; 463 return sun.misc.VM.toThreadState(threadStatus); 464 } 465 466 // These values are defined in jmm.h 467 private static final int JMM_THREAD_STATE_FLAG_MASK = 0xFFF00000; 468 private static final int JMM_THREAD_STATE_FLAG_SUSPENDED = 0x00100000; 469 private static final int JMM_THREAD_STATE_FLAG_NATIVE = 0x00400000; 470 471 }