JVM Management API

10250 ワード

JVM自体は管理されているAPIのセットを提供しています.このAPIを通じて、メモリの各世代のデータ、JVM現在のスレッドとスタックに関する情報など、JVM内部の主要な運行情報を得ることができます.JDKの分析ツールは、jps、jstack、ジンfo、jstat、jmap、jconsolieなど、このAPIに基づいて開発されました.この部分について詳しく説明します.
       参考:http://java.sun.com/javase/6/docs/api/java/lang/management/package-summary.html 一、Management API       まずSun JVMからどのような情報が得られますか?以下の図(JConソロのMBeanの部分からのスクリーンショット)を見ます.      
      1.HotSpot Diagnostic:非標準的な監視JMX、これはSun JVMが持っているもので、主に二つの機能を提供しています.
 
  • JVMの起動パラメータを変更します.(例えば、再起動が必要でない場合は、-XX:+HeappOnOutfMemoryErrパラメータを設定します.JVMメモリが不足しているときは、自動的にdumpがファイルに蓄積されて後続の分析を提供します.)
  • Dumpスタック情報をファイルに、jmapツールはこの機能に基づいて完成された
  • であると推測できる.
         私たちはcomp.sun.managerment.HotSpotDiagnosticMXBen定義を通じてその主要機能を理解します.
    public interface HotSpotDiagnosticMXBean
    {
    void dumpHeap(String s, boolean flag) throws IOException;
    List getDiagnosticOptions();
    VMOption getVMOption(String s);
    void setVMOption(String s, String s1);
    }
         2.Class Loading:ロードされたクラスの全体情報は、このMBeanを通じてJVMにロードされたクラス定義の全体情報を得ることができます.JConsolieのクラス機能はこのMBeanによって提供されるものと推測できます.私たちはjava.lang.managerment.lassLoadingMXBen定義によってその提供する主な機能を知ることができます.
    public interface ClassLoadingMXBean {
    public long getTotalLoadedClassCount();
    public int getLoadedClassCount();
    public long getUnloadedClassCount();
    public boolean isVerbose();
    public void setVerbose(boolean value);
    }
         3.Complation:JVMのJIT(Just In Time)コンパイラ(bytecodeをnative codeにコンパイルする)の情報を提供します.java.lang.maagement.managerment.MXBen定義を通じて、その提供する主な機能を知ることができます.
    public interface CompilationMXBean {
    public java.lang.String    getName();
    public boolean isCompilationTimeMonitoringSupported();
    public long                getTotalCompilationTime();
    }
         4.GarbageCollector:ゴミ回収器情報は、例えば上記の図のように、私達が起動するJVMにはCopyゴミ回収器(Young Genゴミ回収用)とMarkAndSweepゴミ回収器(Tenured Genゴミ回収用)が含まれます.私たちはjava.lang.management.GarbageCollectorMXBen定義によって、その提供する主な機能を知ることができます.
    public interface GarbageCollectorMXBean extends MemoryManagerMXBean {
    public long getCollectionCount();
    public long getCollectionTime();
    }
        java.lang.manage ment.MemoryManager MXBen定義は
    public interface MemoryManagerMXBean {
    public String getName();
    public boolean isValid();
    public String[] getMemoryPoolNames();
    }
        このような情報に加えて、Sun JVMは実現においてLastGCInfoを提供しています.comp.sun.manage ment.GarbageCollectorMXBen定義を参照してください.
    public interface GarbageCollectorMXBean
    extends java.lang.management.GarbageCollectorMXBean
    {
    GcInfo getLastGcInfo();
    }
        私たちは下のスクリーンショットでGcInfoに含まれる主要な情報を知ることができます.   
          その中でjava.lang.managerment.MemoryUsageの後は説明を見ることができます.      5.メモリ関連      JConsolieのメモリ部分の機能はこの部分の関連Beanによって完成されると推測されます.      1)メモリmory/MemoryManager:メモリブロックに関する情報は、このMBeanを通じてメモリ全体の情報を取得し、提供されたgc操作によって強制gcの機能を実行することができます.私たちはjava.lang.managerment.MemoryMXBeanとjava.lang.manager ment.Memory Manager MXBenを通じて、その主に提供される機能を知ることができます.
     
    public interface MemoryMXBean {
    public int getObjectPendingFinalizationCount();
    public MemoryUsage getHeapMemoryUsage();
    public MemoryUsage getNonHeapMemoryUsage();
    public boolean isVerbose();
    public void setVerbose(boolean value);
    public void gc();
    }
          その中でjava.lang.managerment.MemoryUsageは下図を通じてその提供した主な情報を知ることができます.
     
     
    public interface MemoryManagerMXBean {
    public String getName();
    public boolean isValid();
    public String[] getMemoryPoolNames();
    }
         2)メモリブロックの情報は、例えばSun JVMに対して、現在はEden Space、Suvivor Space、Tenurd Gen、CodeCache、Perm Genが含まれています.JConsoneのメモリ監視機能はこのMBeanによって作られたものと推測されます.私たちはjava.lang.manage ment.MemoryPoolMXBenを通じてその主な提供機能を知ることができます.
    public interface MemoryPoolMXBean {
    public String getName();
    public MemoryType getType();
    public MemoryUsage getUsage();
    public MemoryUsage getPeakUsage();
    public void resetPeakUsage();
    public boolean isValid();
    public String[] getMemoryManagerNames();
    public long getUsageThreshold();
    public void setUsageThreshold(long threshold);
    public boolean isUsageThresholdExceeded();
    public long getUsageThresholdCount();
    public boolean isUsageThresholdSupported();
    public long getCollectionUsageThreshold();
    public void setCollectionUsageThreshold(long threhsold);
    public boolean isCollectionUsageThresholdExceeded();
    public long getCollectionUsageThresholdCount();
    public MemoryUsage getCollectionUsage();
    public boolean isCollectionUsageThresholdSupported();
    }
         6.システム運転情報     1)Operating System:MBeanを通じて、JVMが実行しているオペレーティングシステムに関する情報を知ることができます.java.lang.managerment.Operating SystemMXBen定義により、その主に提供されている機能を知ることができます.
    public interface OperatingSystemMXBean {
    public String getName();
    public String getArch();
    public String getVersion();
    public int getAvailableProcessors();
    public double getSystemLoadAverage();
    }
          SunJVMはこの基礎の上でより多くの情報を提供しています.comp.sun.managerment.Operating SystemMXBenを通じていくつかの追加的な情報を知ることができます.
    public interface OperatingSystemMXBean
    extends java.lang.management.OperatingSystemMXBean
    {
    long getCommittedVirtualMemorySize();
    long getTotalSwapSpaceSize();
    long getFreeSwapSpaceSize();
    long getProcessCpuTime();
    long getFreePhysicalMemorySize();
    long getTotalPhysicalMemorySize();
    }
        2)Runtime:MBeanを通じてJVMに関するいくつかの情報を取得し、java.lang.management.RuntimeMXBenを通じて、主に提供された機能を知ることができる.
    public interface RuntimeMXBean {
    public String getName();
    public String getVmName();
    public String getVmVendor();
    public String getVmVersion();
    public String getSpecName();
    public String getSpecVendor();
    public String getSpecVersion();
    public String getManagementSpecVersion();
    public String getClassPath();
    public String getLibraryPath();
    public boolean isBootClassPathSupported();
    public String getBootClassPath();
    public java.util.List<String> getInputArguments();
    public long getUptime();
    public long getStartTime();
    public java.util.Map<String, String> getSystemProperties();
    }
          RuntimeMXBenn.getUptime()とOperating SystemMXBen.get Process CputTime()でJVM占有のシステムCPU比率を計算できる場合、JConsoneのCPUビューはこのように計算されます.      7.Threading:スレッド状態、実行スタックなどを含むMBeanを介してスレッド情報を取得することができます.java.lang.management.ThreadMXBeanを通じて、その提供する主な機能を知ることができます.
    public interface ThreadMXBean {   
    public int getThreadCount();
    public int getPeakThreadCount();
    public long getTotalStartedThreadCount(); 
    public int getDaemonThreadCount();
    public long[] getAllThreadIds();
    public ThreadInfo getThreadInfo(long id);
    public ThreadInfo[] getThreadInfo(long[] ids);
    public ThreadInfo getThreadInfo(long id, int maxDepth);
    public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth);
    public boolean isThreadContentionMonitoringSupported();
    public boolean isThreadContentionMonitoringEnabled();
    public void setThreadContentionMonitoringEnabled(boolean enable);
    public long getCurrentThreadCpuTime();
    public long getCurrentThreadUserTime();
    public long getThreadCpuTime(long id);
    public long getThreadUserTime(long id);
    public boolean isThreadCpuTimeSupported();
    public boolean isCurrentThreadCpuTimeSupported();
    public boolean isThreadCpuTimeEnabled();
    public void setThreadCpuTimeEnabled(boolean enable);
    public long[] findMonitorDeadlockedThreads();
    public void resetPeakThreadCount();
    public long[] findDeadlockedThreads();
    public boolean isObjectMonitorUsageSupported();
    public boolean isSynchronizerUsageSupported();
    public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers);
    public ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers);
    }
         二、プログラミングしてJVM Manage情報を取得しました.JMX方式でJVM Manage定義のMBeanを読み込むことができます.以下の3つの取得方法です.     1.監視アプリケーションと監視アプリケーションは同じJVMにあります.
    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(server,
    "java.lang:type=Runtime", RuntimeMXBean.class);
          2.監視アプリケーションと被監視アプリケーションは同じJVMにありません.      1)まず監視されているJVMの起動パラメータに以下の起動パラメータを入れてJVMエージェントを起動します.
    -Dcomple.sun.managerment.jmxremote-Dcomple.sun.managerment.jmxremote.port=127..0.1:8000-Dcomp.sun.managerment.jmxremote.authenticate=false-Dcome.managerment.jmxretes=
          2)代理に接続する
    JMXServiceURL url = new JMXServiceURL(
    "service:jmx:rmi:///jndi/rmi://127.0.0.1:8000/jmxrmi");
    JMXConnector connector = JMXConnectorFactory.connect(url);
    RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(connector
    .getMBeanServerConnection(),"java.lang:type=Runtime",
    RuntimeMXBean.class);
         3.監視アプリケーションと監視アプリケーションは同じJVMではないが、同じ物理ホスト上にある(2の特化状況は、プロセスAttachを通じて)       私たちはJDKツールを使っていますが、jmapやjstackなどの場合、ツールがあるJVMは当然監視されているJVMと同じではないので、方式1を使用することはできません.監視されているJVMも起動パラメータにJMXのサポートを追加することはありません.幸いなことにSun JVMは監視されているJVMプロセスにAttachを通して3番目の非標準的な方法を提供し、監視されているJVMでJMXエージェントを起動し、2の方式で監視されているJVMのJMXに接続します.以下は使用例です.中で使われている知識はJava Instructment(JVMTIの技術のJava実現)とAttach APIに関連していますので、ここでは詳細な解析を行わないで、後でJava InstrumentとAttach APIを見たら自然に分かります.(JDK 6+だけでサポートします.また、運転にはjdkのtools.jarパッケージが必要です.)
    //Attach  5656 JVM   ,  Attach API   
    VirtualMachine virtualmachine = VirtualMachine.attach("5656");
    // JVM  jmx Agent,    Java Instrutment   
    String javaHome = virtualmachine.getSystemProperties().getProperty("java.home");
    String jmxAgent = javaHome + File.separator + "lib" + File.separator + "management-agent.jar";
    virtualmachine.loadAgent(jmxAgent, "com.sun.management.jmxremote");
    //      
    Properties properties = virtualmachine.getAgentProperties();
    String address = (String)properties.get("com.sun.management.jmxremote.localConnectorAddress");
    //Detach
    virtualmachine.detach();
    JMXServiceURL url = new JMXServiceURL(address);
    JMXConnector connector = JMXConnectorFactory.connect(url);
    RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(connector
    .getMBeanServerConnection(), "java.lang:type=Runtime",RuntimeMXBean.class);
          終わりの言葉      標準インターフェースを通じて、私たちはすでにJVMの運転に関する詳細な情報を得ることができます.JVM、オペレーティングシステムの実行からメモリ、GC、スレッドまで、これらの標準インターフェースを通じて、JVMの機能を完全に監視することができます.しかし、これだけでは足りません.この部分のインターフェースは主にJVMの全体的な情報であり、より多くの詳細を提供することができません.次の部分では、JPDAを使って、JVMの内部情報のより詳細な情報をより深く理解し、どのようにJVM TIを通じて自動的な性能監視を実現するかを知る.