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