Practical Guide to Using JMX Platform MBeans


JMX allows us to monitor local or remote applications. We can use it to detect memory and thread usage, generate heap dump etc.

Local Monitoring
We can call ManagementFactory.getXXMXBean() to get a platform MBean running in the same Java virtual machine.

Remote Monitoring: Using an MXBean Proxy
First, remote application must enable monitoring and management from remote systems, password authentication and ssl is enabled, we may set system property to disable it. We can add the following VM arguments when start remote application:
-Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9999 

Then we can create an MXBean proxy to access a remote MBeanServe.
JMXServiceURL jmxUrl = new JMXServiceURL(
  "service:jmx:rmi:///jndi/rmi://remoteServer:9999/jmxrmi");
  JMXConnector jmxConn = JMXConnectorFactory.connect(jmxUrl);
  MBeanServerConnection mbsc = jmxConn.getMBeanServerConnection();
  MemoryMXBean mbean = ManagementFactory.newPlatformMXBeanProxy(mbsc,
  ManagementFactory.MEMORY_MXBEAN_NAME, MemoryMXBean.class);
Using RuntimeMXBean
RuntimeMXBean can be used to get VM name, version, vendor name, the application class path, input arguments, system properties, up time and start time of the application.

One pratical example is to get the process id of the application.

public static long getPID() {
    RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
    String processName = runtimeMXBean.getName();
    return Long.parseLong(processName.split("@")[0]);
  }
Using ThreadMXBean
ThreadMXBean can be used to get application's thread information, such as get current live threads, peak thread count, total number of threads created, all live thread ids, thread info of one thread, cpu, user time of one thread.

One practical example is to use ThreadMXBean to check whether one thread from third party library is running, we may do or don't do something accordingly.
public static boolean isThreadRunning(String threadName) {
    boolean rhreadRunning = false;
    ThreadMXBean threadMX = ManagementFactory.getThreadMXBean();
    long[] tids = threadMX.getAllThreadIds();
    ThreadInfo[] tinfos = threadMX.getThreadInfo(tids, Integer.MAX_VALUE);
    for (ThreadInfo ti : tinfos) {
      String tName = ti.getThreadName();
      if (tName.startsWith(threadName)) {
        rhreadRunning = true;
      }
    }
    return rhreadRunning;
  }
Another example is to check whether there is deadlock thread in system. 
public static void detectDeadlock() {
    ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
    long[] threadIds = null;
    threadIds = threadBean.findDeadlockedThreads();
    int deadlockedThreads = threadIds != null ? threadIds.length : 0;
    System.out.println("Number of deadlocked threads: " + deadlockedThreads);

    if (threadIds != null) {
      ThreadInfo[] infos = threadBean.getThreadInfo(threadIds);
      for (ThreadInfo info : infos) {
        System.out.println("hanged thread: " + info);
      }
    }
  }
Be sure to use findDeadlockedThreads method in JDK6.0 and newer, not findMonitorDeadlockedThreads.

Solr 3.x threaddump.jsp uses ThreadMXBean to dump all threads.
Using HotSpotDiagnosticMXBean
If we are using Sun JDK, we can use com.sun.management.HotSpotDiagnosticMXBean to generate heap dump for example. This can be useful when we are trying to analyze memory leak, we can generate heap dump every X hours automatically, then compare the memory consumption.
public void generateHeapDump(String fileName, boolean live)
      throws IOException {
    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    HotSpotDiagnosticMXBean bean = ManagementFactory.newPlatformMXBeanProxy(
        server, "com.sun.management:type=HotSpotDiagnostic",
        HotSpotDiagnosticMXBean.class);
    bean.dumpHeap(fileName, live);
  }
Using MemoryMXBean and MemoryPoolMXBean to Monitor Memory Usage
memoryMxBean.getHeapMemoryUsage().getUsed()      <=> runtime.totalMemory() - runtime.freeMemory()
memoryMxBean.getHeapMemoryUsage().getCommitted() <=> runtime.totalMemory()
memoryMxBean.getHeapMemoryUsage().getMax()       <=> runtime.maxMemory()
JDK7: Use com.sun.management.OperatingSystemMXBean to Monitor System and Process CPU Load
Java 7 provides a new MBean that finally allows Java developers to access overall System and current process CPU load monitor.
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
osBean.getProcessCpuLoad();
osBean.getSystemCpuLoad();
Other MXBeans
OperatingSystemMXBean to get operation system info, such as name, arch, number of processors, system average load.
ClassLoadingMXBean to check loaded classes. 
PlatformLoggingMXBean.

Tomcat's Diagnostics.java is a good guide to use platform Mbeans.
jmxstat project in Github provides command to connect to remote JMX server to execute operations at a regular interval.
Resources
Monitoring and Management Using JMX Technology
Tomcat Diagnostics.java
http://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/tomcat/util/Diagnostics.java
Deadlock Detection in Java
Remote Monitoring Heap Memory Usage Using JMX RMI

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)