The following class demonstrates how to connect to a running JVM and establish a JMX connection, loading the JMX agent if necessary. It will print system Properties (this works through a JVM connection without the need for JMX) and memory usage using a MemoryMXBean. It is easy to expand to print other statistics using other types of MXBean.
Note that prior to Java 9, you must add the tools.jar your JDK to the classpath manually. In modular software, you must add a dependency to the jdk.attach module.
import static java.lang.management.ManagementFactory.MEMORY_MXBEAN_NAME; import static java.lang.management.ManagementFactory.newPlatformMXBeanProxy; import java.io.*; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryUsage; import java.util.*; import javax.management.MBeanServerConnection; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import com.sun.tools.attach.*; public class CmdLineTool { static final String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress"; public static void main(String[] args) { if(args.length!=1) System.err.println("Usage: java CmdLineTool <pid>"); else if(printStats(args[0])) return; System.out.println("Currently running"); for(VirtualMachineDescriptor vmd:VirtualMachine.list()) System.out.println(vmd.id()+"\t"+vmd.displayName()); } private static boolean printStats(String id) { try { VirtualMachine vm=VirtualMachine.attach(id); System.out.println("Connected to "+vm.id()); System.out.println("System Properties:"); for(Map.Entry<?,?> en:vm.getSystemProperties().entrySet()) System.out.println("\t"+en.getKey()+" = "+en.getValue()); System.out.println(); try { MBeanServerConnection sc=connect(vm); MemoryMXBean memoryMXBean = newPlatformMXBeanProxy(sc, MEMORY_MXBEAN_NAME, MemoryMXBean.class); getRamInfoHtml(memoryMXBean); } catch(IOException ex) { System.out.println("JMX: "+ex); } vm.detach(); return true; } catch(AttachNotSupportedException | IOException ex) { ex.printStackTrace(); } return false; }
The connect method described above requires Java 8. An alternative for older versions of Java is as follows:
static MBeanServerConnection connect(VirtualMachine vm) throws IOException { String connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); if(connectorAddress == null) { System.out.println("loading agent"); Properties props = vm.getSystemProperties(); String home = props.getProperty("java.home"); String agent = home+File.separator+"lib"+File.separator+"management-agent.jar"; try { vm.loadAgent(agent); } catch (AgentLoadException|AgentInitializationException ex) { throw new IOException(ex); } connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); while(connectorAddress==null) try { Thread.sleep(1000); connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); } catch(InterruptedException ex){} } JMXConnector c=JMXConnectorFactory.connect(new JMXServiceURL(connectorAddress)); return c.getMBeanServerConnection(); }
source share