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

Jus*_*ble 5 java jvm

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

有谁知道有一个 API 可以让我连接到正在运行的 JVM 并收集统计信息吗?

Hol*_*ger 5

以下课程演示如何连接到正在运行的 JVM 并建立 JMX 连接,并在必要时加载 JMX 代理。它将使用 MemoryMXBean 打印系统属性(这通过 JVM 连接进行,无需 JMX)和内存使用情况。它\xe2\x80\x99s 很容易扩展以使用其他 MXBean 类型打印其他统计信息。

\n\n

请注意,在 Java\xc2\xa09 之前,您必须tools.jar手动将您的 JDK 添加到类路径中。在模块化软件中,您必须向jdk.attach模块添加依赖项。

\n\n
import static java.lang.management.ManagementFactory.MEMORY_MXBEAN_NAME;\nimport static java.lang.management.ManagementFactory.newPlatformMXBeanProxy;\n\nimport java.io.*;\nimport java.lang.management.MemoryMXBean;\nimport java.lang.management.MemoryUsage;\nimport java.util.*;\n\nimport javax.management.MBeanServerConnection;\nimport javax.management.remote.JMXConnector;\nimport javax.management.remote.JMXConnectorFactory;\nimport javax.management.remote.JMXServiceURL;\n\nimport com.sun.tools.attach.*;\n\npublic class CmdLineTool\n{\n  static final String CONNECTOR_ADDRESS =\n      "com.sun.management.jmxremote.localConnectorAddress";\n\n  public static void main(String[] args)\n  {\n    if(args.length!=1)\n      System.err.println("Usage: java CmdLineTool <pid>");\n    else if(printStats(args[0])) return;\n    System.out.println("Currently running");\n    for(VirtualMachineDescriptor vmd:VirtualMachine.list())\n      System.out.println(vmd.id()+"\\t"+vmd.displayName());\n  }\n\n  private static boolean printStats(String id)\n  {\n    try\n    {\n      VirtualMachine vm=VirtualMachine.attach(id);\n      System.out.println("Connected to "+vm.id());\n      System.out.println("System Properties:");\n      for(Map.Entry<?,?> en:vm.getSystemProperties().entrySet())\n        System.out.println("\\t"+en.getKey()+" = "+en.getValue());\n      System.out.println();\n      try\n      {\n        MBeanServerConnection sc=connect(vm);\n        MemoryMXBean memoryMXBean =\n          newPlatformMXBeanProxy(sc, MEMORY_MXBEAN_NAME, MemoryMXBean.class);\n        getRamInfoHtml(memoryMXBean);\n      } catch(IOException ex)\n      {\n        System.out.println("JMX: "+ex);\n      }\n      vm.detach();\n      return true;\n    } catch(AttachNotSupportedException | IOException ex)\n    {\n      ex.printStackTrace();\n    }\n    return false;\n  }\n  // requires Java 8, alternative below the code\n  static MBeanServerConnection connect(VirtualMachine vm) throws IOException\n  {\n    String connectorAddress = vm.startLocalManagementAgent();\n    JMXConnector c=JMXConnectorFactory.connect(new JMXServiceURL(connectorAddress));\n    return c.getMBeanServerConnection();\n  }\n\n  static void getRamInfoHtml(MemoryMXBean memoryMXBean)\n  {\n    System.out.print("Heap:\\t");\n    MemoryUsage mu=memoryMXBean.getHeapMemoryUsage();\n    System.out.println(\n      "allocated "+mu.getCommitted()+", used "+mu.getUsed()+", max "+mu.getMax());\n    System.out.print("Non-Heap:\\t");\n    mu=memoryMXBean.getNonHeapMemoryUsage();\n    System.out.println(\n      "allocated "+mu.getCommitted()+", used "+mu.getUsed()+", max "+mu.getMax());\n    System.out.println(\n      "Pending Finalizations: "+memoryMXBean.getObjectPendingFinalizationCount());\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

connect上述解决方法需要Java\xc2\xa08 。旧 Java 版本的替代方案如下所示

\n\n
static MBeanServerConnection connect(VirtualMachine vm) throws IOException\n{\n  String connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);\n  if(connectorAddress == null)\n  {\n    System.out.println("loading agent");\n    Properties props = vm.getSystemProperties();\n    String home  = props.getProperty("java.home");\n    String agent = home+File.separator+"lib"+File.separator+"management-agent.jar";\n    try {\n      vm.loadAgent(agent);\n    } catch (AgentLoadException|AgentInitializationException ex) {\n      throw new IOException(ex);\n    }\n    connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);\n    while(connectorAddress==null) try {\n      Thread.sleep(1000);\n      connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);\n    } catch(InterruptedException ex){}\n  }\n  JMXConnector c=JMXConnectorFactory.connect(new JMXServiceURL(connectorAddress));\n  return c.getMBeanServerConnection();\n}\n
Run Code Online (Sandbox Code Playgroud)\n