1 /* 2 * Copyright (c) 2003, 2008, 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 import sun.security.action.LoadLibraryAction; 41 42 import sun.util.logging.LoggingSupport; 43 44 import java.util.ArrayList; 45 import java.util.Collections; 46 import java.util.List; 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<MemoryPoolMXBean>(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<MemoryManagerMXBean>(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<GarbageCollectorMXBean>(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-complaint MXBean 154 // 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 if (objname == null) { 175 result = Util.newObjectName(LOGGING_MXBEAN_NAME); 176 objname = result; 177 } 178 } 179 } 180 return result; 181 } 182 183 @Override 184 public java.util.List<String> getLoggerNames() { 185 return LoggingSupport.getLoggerNames(); 186 } 187 188 @Override 189 public String getLoggerLevel(String loggerName) { 190 return LoggingSupport.getLoggerLevel(loggerName); 191 } 192 193 @Override 194 public void setLoggerLevel(String loggerName, String levelName) { 195 LoggingSupport.setLoggerLevel(loggerName, levelName); 196 } 197 198 @Override 199 public String getParentLoggerName(String loggerName) { 200 return LoggingSupport.getParentLoggerName(loggerName); 201 } 202 } 203 204 private static List<BufferPoolMXBean> bufferPools = null; 205 public static synchronized List<BufferPoolMXBean> getBufferPoolMXBeans() { 206 if (bufferPools == null) { 207 bufferPools = new ArrayList<>(2); 208 bufferPools.add(createBufferPoolMXBean(sun.misc.SharedSecrets.getJavaNioAccess() 209 .getDirectBufferPool())); 210 bufferPools.add(createBufferPoolMXBean(sun.nio.ch.FileChannelImpl 211 .getMappedBufferPool())); 212 } 213 return bufferPools; 214 } 215 216 private final static String BUFFER_POOL_MXBEAN_NAME = "java.nio:type=BufferPool"; 217 218 /** 219 * Creates management interface for the given buffer pool. 220 */ 221 private static BufferPoolMXBean 222 createBufferPoolMXBean(final sun.misc.JavaNioAccess.BufferPool pool) 223 { 224 return new BufferPoolMXBean() { 225 private volatile ObjectName objname; // created lazily 226 @Override 227 public ObjectName getObjectName() { 228 ObjectName result = objname; 229 if (result == null) { 230 synchronized (this) { 231 if (objname == null) { 232 result = Util.newObjectName(BUFFER_POOL_MXBEAN_NAME + 233 ",name=" + pool.getName()); 234 objname = result; 235 } 236 } 237 } 238 return result; 239 } 240 @Override 241 public String getName() { 242 return pool.getName(); 243 } 244 @Override 245 public long getCount() { 246 return pool.getCount(); 247 } 248 @Override 249 public long getTotalCapacity() { 250 return pool.getTotalCapacity(); 251 } 252 @Override 253 public long getMemoryUsed() { 254 return pool.getMemoryUsed(); 255 } 256 }; 257 } 258 259 private static HotSpotDiagnostic hsDiagMBean = null; 260 private static HotspotRuntime hsRuntimeMBean = null; 261 private static HotspotClassLoading hsClassMBean = null; 262 private static HotspotThread hsThreadMBean = null; 263 private static HotspotCompilation hsCompileMBean = null; 264 private static HotspotMemory hsMemoryMBean = null; 265 266 public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() { 267 if (hsDiagMBean == null) { 268 hsDiagMBean = new HotSpotDiagnostic(); 269 } 270 return hsDiagMBean; 271 } 272 273 /** 274 * This method is for testing only. 275 */ 276 public static synchronized HotspotRuntimeMBean getHotspotRuntimeMBean() { 277 if (hsRuntimeMBean == null) { 278 hsRuntimeMBean = new HotspotRuntime(jvm); 279 } 280 return hsRuntimeMBean; 281 } 282 283 /** 284 * This method is for testing only. 285 */ 286 public static synchronized HotspotClassLoadingMBean getHotspotClassLoadingMBean() { 287 if (hsClassMBean == null) { 288 hsClassMBean = new HotspotClassLoading(jvm); 289 } 290 return hsClassMBean; 291 } 292 293 /** 294 * This method is for testing only. 295 */ 296 public static synchronized HotspotThreadMBean getHotspotThreadMBean() { 297 if (hsThreadMBean == null) { 298 hsThreadMBean = new HotspotThread(jvm); 299 } 300 return hsThreadMBean; 301 } 302 303 /** 304 * This method is for testing only. 305 */ 306 public static synchronized HotspotMemoryMBean getHotspotMemoryMBean() { 307 if (hsMemoryMBean == null) { 308 hsMemoryMBean = new HotspotMemory(jvm); 309 } 310 return hsMemoryMBean; 311 } 312 313 /** 314 * This method is for testing only. 315 */ 316 public static synchronized HotspotCompilationMBean getHotspotCompilationMBean() { 317 if (hsCompileMBean == null) { 318 hsCompileMBean = new HotspotCompilation(jvm); 319 } 320 return hsCompileMBean; 321 } 322 323 /** 324 * Registers a given MBean if not registered in the MBeanServer; 325 * otherwise, just return. 326 */ 327 private static void addMBean(MBeanServer mbs, Object mbean, String mbeanName) { 328 try { 329 final ObjectName objName = Util.newObjectName(mbeanName); 330 331 // inner class requires these fields to be final 332 final MBeanServer mbs0 = mbs; 333 final Object mbean0 = mbean; 334 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { 335 public Void run() throws MBeanRegistrationException, 336 NotCompliantMBeanException { 337 try { 338 mbs0.registerMBean(mbean0, objName); 339 return null; 340 } catch (InstanceAlreadyExistsException e) { 341 // if an instance with the object name exists in 342 // the MBeanServer ignore the exception 343 } 344 return null; 345 } 346 }); 347 } catch (PrivilegedActionException e) { 348 throw Util.newException(e.getException()); 349 } 350 } 351 352 private final static String HOTSPOT_CLASS_LOADING_MBEAN_NAME = 353 "sun.management:type=HotspotClassLoading"; 354 355 private final static String HOTSPOT_COMPILATION_MBEAN_NAME = 356 "sun.management:type=HotspotCompilation"; 357 358 private final static String HOTSPOT_MEMORY_MBEAN_NAME = 359 "sun.management:type=HotspotMemory"; 360 361 private static final String HOTSPOT_RUNTIME_MBEAN_NAME = 362 "sun.management:type=HotspotRuntime"; 363 364 private final static String HOTSPOT_THREAD_MBEAN_NAME = 365 "sun.management:type=HotspotThreading"; 366 367 static void registerInternalMBeans(MBeanServer mbs) { 368 // register all internal MBeans if not registered 369 // No exception is thrown if a MBean with that object name 370 // already registered 371 addMBean(mbs, getHotspotClassLoadingMBean(), 372 HOTSPOT_CLASS_LOADING_MBEAN_NAME); 373 addMBean(mbs, getHotspotMemoryMBean(), 374 HOTSPOT_MEMORY_MBEAN_NAME); 375 addMBean(mbs, getHotspotRuntimeMBean(), 376 HOTSPOT_RUNTIME_MBEAN_NAME); 377 addMBean(mbs, getHotspotThreadMBean(), 378 HOTSPOT_THREAD_MBEAN_NAME); 379 380 // CompilationMBean may not exist 381 if (getCompilationMXBean() != null) { 382 addMBean(mbs, getHotspotCompilationMBean(), 383 HOTSPOT_COMPILATION_MBEAN_NAME); 384 } 385 } 386 387 private static void unregisterMBean(MBeanServer mbs, String mbeanName) { 388 try { 389 final ObjectName objName = Util.newObjectName(mbeanName); 390 391 // inner class requires these fields to be final 392 final MBeanServer mbs0 = mbs; 393 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { 394 public Void run() throws MBeanRegistrationException, 395 RuntimeOperationsException { 396 try { 397 mbs0.unregisterMBean(objName); 398 } catch (InstanceNotFoundException e) { 399 // ignore exception if not found 400 } 401 return null; 402 } 403 }); 404 } catch (PrivilegedActionException e) { 405 throw Util.newException(e.getException()); 406 } 407 } 408 409 static void unregisterInternalMBeans(MBeanServer mbs) { 410 // unregister all internal MBeans 411 unregisterMBean(mbs, HOTSPOT_CLASS_LOADING_MBEAN_NAME); 412 unregisterMBean(mbs, HOTSPOT_MEMORY_MBEAN_NAME); 413 unregisterMBean(mbs, HOTSPOT_RUNTIME_MBEAN_NAME); 414 unregisterMBean(mbs, HOTSPOT_THREAD_MBEAN_NAME); 415 416 // CompilationMBean may not exist 417 if (getCompilationMXBean() != null) { 418 unregisterMBean(mbs, HOTSPOT_COMPILATION_MBEAN_NAME); 419 } 420 } 421 422 static { 423 AccessController.doPrivileged(new LoadLibraryAction("management")); 424 jvm = new VMManagementImpl(); 425 } 426 427 public static boolean isThreadSuspended(int state) { 428 return ((state & JMM_THREAD_STATE_FLAG_SUSPENDED) != 0); 429 } 430 431 public static boolean isThreadRunningNative(int state) { 432 return ((state & JMM_THREAD_STATE_FLAG_NATIVE) != 0); 433 } 434 435 public static Thread.State toThreadState(int state) { 436 // suspended and native bits may be set in state 437 int threadStatus = state & ~JMM_THREAD_STATE_FLAG_MASK; 438 return sun.misc.VM.toThreadState(threadStatus); 439 } 440 441 // These values are defined in jmm.h 442 private static final int JMM_THREAD_STATE_FLAG_MASK = 0xFFF00000; 443 private static final int JMM_THREAD_STATE_FLAG_SUSPENDED = 0x00100000; 444 private static final int JMM_THREAD_STATE_FLAG_NATIVE = 0x00400000; 445 446 }