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. Delphi的时间 x87 fpu control word 精度设置的不够

    在win7 64位系统下, 一个DELPHI写的DLL注入一个C语言程序后. 出现非常奇怪的浮点数相加出错的情况. (注: 在XP系统下是正常的).比如: 40725.0001597563 + 0.7 ...

  2. eclipse:报错信息The superclass “javax.servlet.http.HttpServlet” was not found on the Java Build Path

    JavaWeb: 报错信息The superclass "javax.servlet.http.HttpServlet" was not found on the Java Bui ...

  3. ★★★【卡法 常用js库】: js汇合 表单验证 cookie设置 日期格式 电话手机号码 email 整数 小数 金额 检查参数长度

    [卡法 常用js库]: js汇合 表单验证  cookie设置  日期格式  电话手机号码  email  整数  小数  金额   检查参数长度 // +---------------------- ...

  4. zookeeper的理解与概述

    文章转自https://www.cnblogs.com/likehua/p/3999600.html  感谢博主 文章转自:http://www.aboutyun.com/thread-9266-1- ...

  5. Vue简单用法目录总结 以及 前端基础总结传送门:

    Vue官方网址:https://cn.vuejs.org/ Vue 第三方组件:Element:http://element-cn.eleme.io/#/zh-CN Vue 基础指令以及自定义指令:h ...

  6. POJ 3204 网络流的必须边

    思路: 求一遍网络流 在残余网络上DFS 从起点DFS 从终点把边反向DFS 一个边跟起点连通 跟终点反向的边连通 ans++ 注:此题不能用tarjan 因为有边权为0的边 //By SiriusR ...

  7. Java基础学习总结(10)——static关键字

    一.static关键字 原来一个类里面的成员变量,每new一个对象,这个对象就有一份自己的成员变量,因为这些成员变量都不是静态成员变量.对于static成员变量来说,这个成员变量只有一份,而且这一份是 ...

  8. iOS开发之软键盘使用小技巧

    在iOS开发过程中,有时候须要弹出软键盘进行输入,有时候又须要在某些情况下隐藏软键盘,以提高用户体验. 今天有几个关于软键盘的小技巧和大家分享. (1)仅仅弹出数字键盘 有某些需求中,要求用户仅仅能在 ...

  9. 离散化求RECT1

    本文转载至点击打开链接 #include<stdio.h> struct node{ int x1,y1,x2,y2,c; }; struct node s[1010]; int px[2 ...

  10. IOS &#39;NSInternalInconsistencyException&#39;

    今天想写一个请求的天气.好的.废话不多说.先贴代码: 使用AFNetWorking 发送get请求,可是一直报错  IOS 'NSInternalInconsistencyException', re ...