zoukankan      html  css  js  c++  java
  • jvm 性能分析

    VM本身提供了一组管理的API,通过该API,我们可以获取得到JVM内部主要运行信息,包括内存各代的数据、JVM当前所有线程及其栈相关信息等等。各种JDK自带的剖析工具,包括jps、jstack、jinfo、jstat、jmap、jconsole等,都是基于此API开发的。本篇对这部分内容进行一个详细的说明。

           参考:http://java.sun.com/javase/6/docs/api/java/lang/management/package-summary.html 
    一、Management API
           我们先看一下从Sun JVM我们可以获取到哪些信息,如下图(来自于JConsole的MBean部分的截图):
           
          1.HotSpotDiagnostic:非标准的监控JMX,这块是Sun JVM自带的,主要提供了两个功能

    • 修改JVM的启动参数(譬如在不需要重启的情况下设置-XX:+HeapDumpOnOutOfMemoryError参数使得JVM内存不足的时候自动dump出堆空间到文件提供后续分析)
    • Dump堆信息到文件,可以猜测jmap工具是基于此功能来完成的

         我们通过com.sun.management.HotSpotDiagnosticMXBean定义了解其主要功能

    Java代码  收藏代码
    1. public interface HotSpotDiagnosticMXBean  
    2. {  
    3.     void dumpHeap(String s, boolean flag) throws IOException;  
    4.     List getDiagnosticOptions();  
    5.     VMOption getVMOption(String s);  
    6.     void setVMOption(String s, String s1);  
    7. }  

         2.ClassLoading:加载的类的总体信息,我们可以通过此MBean获取到JVM加载的类定义的总体信息,可以猜测JConsole的类功能就是通过此MBean来提供的。我们可以通过java.lang.management.ClassLoadingMXBean定义了解其提供的主要功能

    Java代码  收藏代码
    1. public interface ClassLoadingMXBean {  
    2.     public long getTotalLoadedClassCount();  
    3.     public int getLoadedClassCount();  
    4.     public long getUnloadedClassCount();  
    5.     public boolean isVerbose();  
    6.     public void setVerbose(boolean value);  
    7. }  

         3.Compilation:提供JVM的JIT(Just In Time)编译器(将bytecode编译成native code)的信息,我们可以通过java.lang.management.CompilationMXBean定义了解其提供的主要功能

    Java代码  收藏代码
    1. public interface CompilationMXBean {  
    2.     public java.lang.String    getName();  
    3.     public boolean isCompilationTimeMonitoringSupported();  
    4.     public long                getTotalCompilationTime();  
    5. }  

         4.GarbageCollector:垃圾回收器信息,譬如在如上图中,我们启动的JVM会包含一个Copy垃圾回收器(用于Young Gen垃圾回收)和一个MarkAndSweep垃圾回收器(用于Tenured Gen垃圾回收)。我们可以通过java.lang.management.GarbageCollectorMXBean定义了解其提供的主要功能

    Java代码  收藏代码
    1. public interface GarbageCollectorMXBean extends MemoryManagerMXBean {  
    2.     public long getCollectionCount();  
    3.     public long getCollectionTime();  
    4. }  

        java.lang.management.MemoryManagerMXBean定义是

    Java代码  收藏代码
    1. public interface MemoryManagerMXBean {  
    2.     public String getName();  
    3.     public boolean isValid();  
    4.     public String[] getMemoryPoolNames();  
    5. }  

        除了如上信息,Sun JVM在实现上还提供了一个额外的信息LastGCInfo,见com.sun.management.GarbageCollectorMXBean定义

    Java代码  收藏代码
    1. public interface GarbageCollectorMXBean  
    2.     extends java.lang.management.GarbageCollectorMXBean  
    3. {  
    4.     GcInfo getLastGcInfo();  
    5. }  

        我们可以通过下面的截图了解GcInfo包含的主要信息
        
          其中java.lang.management.MemoryUsage后续可以看说明
          5.内存相关
          可以猜测,JConsole的内存部分的功能都是通过此部分的相关Bean来完成的。
          1)Memory/MemoryManager:内存块相关信息,通过这MBean我们可以获取到内存的总体信息,并可以通过提供的gc操作进行强制gc的功能(System.gc())。我们可以通过java.lang.management.MemoryMXBean和java.lang.management.MemoryManagerMXBean了解其主要提供的功能

    Java代码  收藏代码
    1. public interface MemoryMXBean {  
    2.     public int getObjectPendingFinalizationCount();  
    3.     public MemoryUsage getHeapMemoryUsage();  
    4.     public MemoryUsage getNonHeapMemoryUsage();  
    5.     public boolean isVerbose();  
    6.     public void setVerbose(boolean value);  
    7.     public void gc();  
    8. }  

          其中java.lang.management.MemoryUsage我们可以通过下图来了解其提供的主要信息

    Java代码  收藏代码
    1. public interface MemoryManagerMXBean {  
    2.     public String getName();  
    3.     public boolean isValid();  
    4.     public String[] getMemoryPoolNames();  
    5. }  

         2)MemoryPool:通过该MBean可以了解JVM各内存块的信息,譬如对于Sun JVM,目前包括Eden Space、Suvivor Space、Tenured Gen、CodeCache、Perm Gen,可以猜测JConsole的内存监控功能就是通过此MBean来做到的。我们可以通过java.lang.management.MemoryPoolMXBean了解其主要提供的功能

    Java代码  收藏代码
    1. public interface MemoryPoolMXBean {  
    2.     public String getName();  
    3.     public MemoryType getType();  
    4.     public MemoryUsage getUsage();  
    5.     public MemoryUsage getPeakUsage();  
    6.     public void resetPeakUsage();  
    7.     public boolean isValid();  
    8.     public String[] getMemoryManagerNames();  
    9.     public long getUsageThreshold();  
    10.     public void setUsageThreshold(long threshold);  
    11.     public boolean isUsageThresholdExceeded();  
    12.     public long getUsageThresholdCount();  
    13.     public boolean isUsageThresholdSupported();  
    14.     public long getCollectionUsageThreshold();  
    15.     public void setCollectionUsageThreshold(long threhsold);  
    16.     public boolean isCollectionUsageThresholdExceeded();  
    17.     public long getCollectionUsageThresholdCount();  
    18.     public MemoryUsage getCollectionUsage();  
    19.     public boolean isCollectionUsageThresholdSupported();  
    20. }  

         6.系统运行信息
         1)OperatingSystem:通过该MBean我们可以了解到JVM所运行在的操作系统上的一些相关信息,通过java.lang.management.OperatingSystemMXBean定义我们可以了解到其主要提供的功能

    Java代码  收藏代码
    1. public interface OperatingSystemMXBean {  
    2.     public String getName();  
    3.     public String getArch();  
    4.     public String getVersion();  
    5.     public int getAvailableProcessors();  
    6.     public double getSystemLoadAverage();  
    7. }  

          SunJVM在此基础上提供更多的一些信息,可以通过com.sun.management.OperatingSystemMXBean了解一些额外可以获取到的信息

    Java代码  收藏代码
    1. public interface OperatingSystemMXBean  
    2.     extends java.lang.management.OperatingSystemMXBean  
    3. {  
    4.     long getCommittedVirtualMemorySize();  
    5.     long getTotalSwapSpaceSize();  
    6.     long getFreeSwapSpaceSize();  
    7.     long getProcessCpuTime();  
    8.     long getFreePhysicalMemorySize();  
    9.     long getTotalPhysicalMemorySize();  
    10. }  

        2)Runtime:通过该MBean获取获取到JVM一些相关的信息,通过java.lang.management.RuntimeMXBean可以了解其主要提供的功能

    Java代码  收藏代码
    1. public interface RuntimeMXBean {  
    2.     public String getName();  
    3.     public String getVmName();  
    4.     public String getVmVendor();  
    5.     public String getVmVersion();  
    6.     public String getSpecName();  
    7.     public String getSpecVendor();  
    8.     public String getSpecVersion();  
    9.     public String getManagementSpecVersion();  
    10.     public String getClassPath();  
    11.     public String getLibraryPath();  
    12.     public boolean isBootClassPathSupported();  
    13.     public String getBootClassPath();  
    14.     public java.util.List<String> getInputArguments();  
    15.     public long getUptime();  
    16.     public long getStartTime();  
    17.     public java.util.Map<String, String> getSystemProperties();  
    18. }  

          可以通过RuntimeMXBean.getUptime()和OperatingSystemMXBean. getProcessCpuTime()来计算JVM占用的系统CPU比例的情况,JConsole的CPU视图就是通过这种方式计算的。
          7.Threading:可以通过该MBean获取线程信息,包括线程状态、执行栈等。可以通过java.lang.management.ThreadMXBean了解其提供的主要功能

    Java代码  收藏代码
    1. public interface ThreadMXBean {     
    2.    public int getThreadCount();  
    3.     public int getPeakThreadCount();  
    4.     public long getTotalStartedThreadCount();   
    5.     public int getDaemonThreadCount();  
    6.     public long[] getAllThreadIds();  
    7.     public ThreadInfo getThreadInfo(long id);  
    8.     public ThreadInfo[] getThreadInfo(long[] ids);  
    9.     public ThreadInfo getThreadInfo(long id, int maxDepth);  
    10.     public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth);  
    11.     public boolean isThreadContentionMonitoringSupported();  
    12.     public boolean isThreadContentionMonitoringEnabled();  
    13.     public void setThreadContentionMonitoringEnabled(boolean enable);  
    14.     public long getCurrentThreadCpuTime();  
    15.     public long getCurrentThreadUserTime();  
    16.     public long getThreadCpuTime(long id);  
    17.     public long getThreadUserTime(long id);  
    18.     public boolean isThreadCpuTimeSupported();  
    19.     public boolean isCurrentThreadCpuTimeSupported();  
    20.     public boolean isThreadCpuTimeEnabled();  
    21.     public void setThreadCpuTimeEnabled(boolean enable);  
    22.     public long[] findMonitorDeadlockedThreads();  
    23.     public void resetPeakThreadCount();  
    24.     public long[] findDeadlockedThreads();  
    25.     public boolean isObjectMonitorUsageSupported();  
    26.     public boolean isSynchronizerUsageSupported();  
    27.     public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers);  
    28.     public ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers);  
    29. }  

         二、编程获取到JVM Manage信息
    我们可以通过JMX的方式读取到JVM Manage定义的MBean,如下是3种获取方法
         1.监控应用与被监控应用位于同一JVM

    Java代码  收藏代码
    1. MBeanServer server = ManagementFactory.getPlatformMBeanServer();  
    2. RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(server,  
    3.                 "java.lang:type=Runtime", RuntimeMXBean.class);  

          2.监控应用与被监控应用不位于同一JVM
          1)首先在被监控的JVM的启动参数中加入如下的启动参数以启JVM代理

    -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=127.0.0.1:8000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

          2)连接到代理上

    Java代码  收藏代码
    1. JMXServiceURL url = new JMXServiceURL(  
    2.         "service:jmx:rmi:///jndi/rmi://127.0.0.1:8000/jmxrmi");  
    3. JMXConnector connector = JMXConnectorFactory.connect(url);  
    4. RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(connector  
    5.             .getMBeanServerConnection(),"java.lang:type=Runtime",  
    6.                 RuntimeMXBean.class);  

         3.监控应用与被监控应用不位于同一JVM但在同一物理主机上(2的特化情况,通过进程Attach)
           我们使用JDK工具,如jmap、jstack等的时候,工具所在的JVM当然与被监控的JVM不是同一个,所以不能使用方式1,被监控的JVM一般也不会在启动参数中增加JMX的支持,所以方式2也没有办法。还好Sun JVM给我们提供了第3种非标准的方式,就是通过Attach到被监控的JVM进程,并在被监控的JVM中启动一个JMX代理,然后使用该代理通过2的方式连接到被监控的JVM的JMX上。下面是一个使用范例,由于里面使用到的知识涉及到Java Instrutment(JVMTI的一个技术的Java实现)和Attach API,因此此处不做详细解析,在后续看完Java Instrutment和Attach API自然就会明白。(注意,仅在JDK6+中支持,另外,运行需要jdk的tools.jar包)

  • 相关阅读:
    PAT甲题题解-1030. Travel Plan (30)-最短路+输出路径
    PAT甲题题解-1029. Median (25)-求两序列的中位数,题目更新了之后不水了
    PAT甲题题解-1028. List Sorting (25)-水排序
    BZOJ 1492 货币兑换Cash
    Codeforces 276D Little Girl and Maximum XOR
    Codeforces 526E Transmitting Levels
    Codeforces 335B Palindrome
    BZOJ 2527 Meteors
    Codeforces 449D Jzzhu and Numbers
    FJ省队集训DAY4 T3
  • 原文地址:https://www.cnblogs.com/diyunpeng/p/6852309.html
Copyright © 2011-2022 走看看