用于从运行JVM收集统计信息的API [英] API to gather statistics from running JVM

查看:155
本文介绍了用于从运行JVM收集统计信息的API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For a class project, I would like to implement a Java application that connects to a local JVM and gathers statistics such as heap usage, number of threads, loaded classes etc. I've searched online for an API, third party of built-in, that would allow me to do this but I have so far been unsuccessful.

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

Does anyone know of an API that will allow me to connect to a running JVM and gather statistics?

推荐答案

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

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 the JVM connection without the need for JMX) and the memory usage using the MemoryMXBean. It’s easy to extend to print other statistics using other MXBean types.

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

Note, that you have to add the tools.jar of your JDK to the classpath manually.

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 <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);
        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());
  }
}

这篇关于用于从运行JVM收集统计信息的API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆