用于从运行JVM收集统计信息的API

对于一个类项目,我想实现一个连接到本地JVM的Java应用程序,并收集堆使用情况,线程数,加载的类等统计信息。我在网上搜索了一个API,内置的第三方,这将允许我这样做,但到目前为止我没有成功。

有没有人知道一个API,它允许我连接到正在运行的JVM并收集统计信息?

以下类演示如何连接到正在运行的JVM并建立JMX连接,并在必要时加载JMX代理。 它将打印系统属性(这通过JVM连接而不需要JMX)和使用MemoryMXBean的内存使用。 使用其他MXBean类型可以轻松扩展以打印其他统计信息。

请注意,您必须手动将JDK的tools.jar添加到类路径中。

 import static java.lang.management.ManagementFactory.MEMORY_MXBEAN_NAME; import static java.lang.management.ManagementFactory.newPlatformMXBeanProxy; import java.io.File; import java.io.IOException; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryUsage; import java.util.Map; import java.util.Properties; 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 "); 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); System.out.println(); getRamInfoHtml(memoryMXBean); } catch(AgentLoadException | AgentInitializationException ex) { System.out.println("JMX: "+ex); } vm.detach(); return true; } catch(AttachNotSupportedException | IOException ex) { ex.printStackTrace(); } return false; } static MBeanServerConnection connect(VirtualMachine vm) throws AgentLoadException, AgentInitializationException, 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"; vm.loadAgent(agent); 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(); } static void getRamInfoHtml(MemoryMXBean memoryMXBean) { System.out.print("Heap:\t"); MemoryUsage mu=memoryMXBean.getHeapMemoryUsage(); System.out.println("allocated "+mu.getCommitted()+", used "+mu.getUsed()+", max "+mu.getMax()); System.out.print("Non-Heap:\t"); mu=memoryMXBean.getNonHeapMemoryUsage(); System.out.println("allocated "+mu.getCommitted()+", used "+mu.getUsed()+", max "+mu.getMax()); System.out.println("Pending Finalizations: "+memoryMXBean.getObjectPendingFinalizationCount()); } } 

VisualVM通过Java API公开了它的一些function。 注意,这些是在com.sun.tools.*包中,而不是通常的java.*javax.*包。

有关如何使用这些API的更多信息,请参阅入门扩展VisualVM 。

有一个名为JVMTool Interface的本机api

如果需要来自正在运行的JVM的统计信息,可以使用JDK附带的VisualVM 。 它为jvm上的所有正在运行的进程提供统计信息。