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包)

jvm 性能分析的更多相关文章

  1. JVM性能分析与优化

    JVM性能分析与优化: http://www.docin.com/p-757199232.html

  2. JVM性能分析工具详解--MAT等

    获得堆转储文件 巧妇难为无米之炊,我们首先需要获得一个堆转储文件.为了方便,本文采用的是 Sun JDK 6.通常来说,只要你设置了如下所示的 JVM 参数: -XX:+HeapDumpOnOutOf ...

  3. JVM性能分析 | 一次生产系统Full GC问题分析与排查总结

    一次生产系统Full GC问题分析与排查总结 背景 最近某线上业务系统生产环境频频CPU使用率过低,频繁告警,通过重启可以缓解,但是过了一段时间又会继续预警,线上两个服务节点相继出现CPU资源紧张,导 ...

  4. 【J2EE性能分析篇】JVM参数对J2EE性能优化的影响

    一切J2EE应用都是基于JVM的,那么对于JVM的设置和监控,成为J2EE应用程序性能分析和性能优化的必然手段.今天Sincky和大家交流该话题.这里以Tomcat环境为例,其它WEB服务器如Jbos ...

  5. 【转】JVM虚拟性能分析

    JDK自带的JAVA性能分析工具.它已经在你的JDK bin目录里了,只要你使用的是JDK1.6 Update7之后的版本.点击一下jvisualvm.exe图标它就可以运行了. 这里是VisualV ...

  6. Java 性能分析工具 , 第 3 部分: Java Mission Control

    引言 本文为 Java 性能分析工具系列文章第三篇,这里将介绍如何使用 Java 任务控制器 Java Mission Control 深入分析 Java 应用程序的性能,为程序开发人员在使用 Jav ...

  7. Java 性能分析工具 , 第 2 部分:Java 内置监控工具

    引言 本文为 Java 性能分析工具系列文章第二篇,第一篇:操作系统工具.在本文中将介绍如何使用 Java 内置监控工具更加深入的了解 Java 应用程序和 JVM 本身.在 JDK 中有许多内置的工 ...

  8. 性能分析神器VisualVM

    VisualVM 是一款免费的,集成了多个 JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优.这些功能包括生成和分析海量数据.跟踪内存泄漏.监控垃圾回 ...

  9. jvm性能监控与故障处理工具

    jdk为我们提供了一系列的jvm性能监控和故障处理工具,在这里根据学习进度进行整理记录.便于之后查阅 1.jps 虚拟机进程工具  类似于Linux系统中的ps命令,用于查看虚拟机进程,常用的有以下功 ...

随机推荐

  1. zzulioj--1804--ZY学长的密码(字符串)

    1804: ZY学长的密码 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 140  Solved: 53 SubmitStatusWeb Board ...

  2. rest_framework 分页三种

    .分页 a. 分页 看第n页 每页显示n条数据: b. 分页 在某个位置 向后查看多少条数据 c. 加密分页 上一页和下一页 本质:查看 记住页码id的最大值和最小值 通过其来准确扫描 过去的话 会从 ...

  3. Filenames and paths

    Files are organized into directories (also called ‘folders’). Every running program has a ‘current d ...

  4. OpenGL编程逐步深入(五)Uniform 变量

    准备知识 在这个教程中我们会遇到一种新的Shader变量类型,即uniform变量.attribute(属性)变量和uniform变量的不同之处在于attribute 变量中包含顶点的具体数据,当每次 ...

  5. shell脚本备份nginx日志

    vim /data/runlog.sh                                                  #编辑一个 shell 脚本 #!/bin/bash LOGP ...

  6. fuser ---显示出当前程序使用磁盘上的某个文件

    fuser 可以显示出当前哪个程序在使用磁盘上的某个文件.挂载点.甚至网络端口,并给出程序进程的详细信息. fuser只把PID输出到标准输出,其他的都输出到标准错误输出. a 显示所有命令行中指定的 ...

  7. 今日SGU 6.6

    sgu 177 题意:给你一个一开始全是白色的正方形,边长为n,然后问你经过几次染色之后,最后的矩形里面 还剩多少个白色的块 收获:矩形切割,我们可以这么做,离散处理,对于每次染黑的操作,看看后面有没 ...

  8. tt

    Oracle报错处理 1.oem启动报错 解决方案:

  9. Spring Cloud学习笔记【八】服务网关 Zuul(过滤器)

    在上篇文章中我们了解了 Spring Cloud Zuul 作为网关所具备的最基本功能:路由(Router),下面我们将关注 Spring Cloud Zuul 的另一核心功能:过滤器(Filter) ...

  10. POJ——T 1986 Distance Queries

    http://poj.org/problem?id=1986 Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 14383   ...