4

クラス プロジェクトの場合、ローカル JVM に接続し、ヒープ使用量、スレッド数、ロードされたクラスなどの統計を収集する Java アプリケーションを実装したいと考えています。組み込みの API、サード パーティをオンラインで検索しました。 、これを行うことができますが、これまでのところ成功していません。

実行中の JVM に接続して統計を収集できる API を知っている人はいますか?

4

3 に答える 3

4

次のクラスは、実行中の JVM に接続して JMX 接続を確立し、必要に応じて JMX エージェントをロードする方法を示しています。システム プロパティ (これは JMX を必要とせずに JVM 接続を介して機能します) と、MemoryMXBean を使用したメモリ使用量を出力します。他の MXBean タイプを使用して他の統計を出力するように拡張するのは簡単です。

tools.jarJava 9 より前では、JDK を手動でクラスパスに追加する必要があることに注意してください。モジュラー ソフトウェアでは、モジュールに依存関係を追加する必要がありjdk.attachます。

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;
  }
  // requires Java 8, alternative below the code
  static MBeanServerConnection connect(VirtualMachine vm) throws IOException
  {
    String connectorAddress = vm.startLocalManagementAgent();
    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());
  }
}

上記のソリューションのconnect方法には Java 8 が必要です。古い Java バージョンの代替は次のようになります。

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();
}
于 2013-10-16T09:41:12.647 に答える
1

VisualVMは、その機能の一部を Java API を通じて公開します。これらはcom.sun.tools.*通常のパッケージではなくパッケージjava.*に含まれていることに注意してくださいjavax.*

これらの API の使用方法の詳細については、 Getting Started Extending VisualVMを参照してください。

于 2013-10-16T03:29:32.493 に答える
0

JVMTool Interfaceというネイティブ API があります。

実行中の JVM からの統計が必要な場合は、JDK に同梱されているVisualVMを使用できます。jvm で実行中のすべてのプロセスの統計を提供します。

于 2013-10-16T03:29:02.130 に答える