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定义了解其主要功能
- public interface HotSpotDiagnosticMXBean
- {
- void dumpHeap(String s, boolean flag) throws IOException;
- List getDiagnosticOptions();
- VMOption getVMOption(String s);
- void setVMOption(String s, String s1);
- }
2.ClassLoading:加载的类的总体信息,我们可以通过此MBean获取到JVM加载的类定义的总体信息,可以猜测JConsole的类功能就是通过此MBean来提供的。我们可以通过java.lang.management.ClassLoadingMXBean定义了解其提供的主要功能
- public interface ClassLoadingMXBean {
- public long getTotalLoadedClassCount();
- public int getLoadedClassCount();
- public long getUnloadedClassCount();
- public boolean isVerbose();
- public void setVerbose(boolean value);
- }
3.Compilation:提供JVM的JIT(Just In Time)编译器(将bytecode编译成native
code)的信息,我们可以通过java.lang.management.CompilationMXBean定义了解其提供的主要功能
- 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.GarbageCollectorMXBean定义了解其提供的主要功能
- public interface GarbageCollectorMXBean extends MemoryManagerMXBean {
- public long getCollectionCount();
- public long getCollectionTime();
- }
java.lang.management.MemoryManagerMXBean定义是
- public interface MemoryManagerMXBean {
- public String getName();
- public boolean isValid();
- public String[] getMemoryPoolNames();
- }
除了如上信息,Sun
JVM在实现上还提供了一个额外的信息LastGCInfo,见com.sun.management.GarbageCollectorMXBean定义
- public interface GarbageCollectorMXBean
- extends java.lang.management.GarbageCollectorMXBean
- {
- GcInfo getLastGcInfo();
- }
我们可以通过下面的截图了解GcInfo包含的主要信息

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

- public interface MemoryManagerMXBean {
- public String getName();
- public boolean isValid();
- public String[] getMemoryPoolNames();
- }
2)MemoryPool:通过该MBean可以了解JVM各内存块的信息,譬如对于Sun JVM,目前包括Eden
Space、Suvivor Space、Tenured Gen、CodeCache、Perm
Gen,可以猜测JConsole的内存监控功能就是通过此MBean来做到的。我们可以通过java.lang.management.MemoryPoolMXBean了解其主要提供的功能
- 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)OperatingSystem:通过该MBean我们可以了解到JVM所运行在的操作系统上的一些相关信息,通过java.lang.management.OperatingSystemMXBean定义我们可以了解到其主要提供的功能
- public interface OperatingSystemMXBean {
- public String getName();
- public String getArch();
- public String getVersion();
- public int getAvailableProcessors();
- public double getSystemLoadAverage();
- }
SunJVM在此基础上提供更多的一些信息,可以通过com.sun.management.OperatingSystemMXBean了解一些额外可以获取到的信息
- 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.RuntimeMXBean可以了解其主要提供的功能
- 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();
- }
可以通过RuntimeMXBean.getUptime()和OperatingSystemMXBean.
getProcessCpuTime()来计算JVM占用的系统CPU比例的情况,JConsole的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代理
-Dcom.sun.management.jmxremote.port=127.0.0.1:8000
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
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的支持,所以方式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 性能分析的更多相关文章
- JVM性能分析与优化
JVM性能分析与优化: http://www.docin.com/p-757199232.html
- JVM性能分析工具详解--MAT等
获得堆转储文件 巧妇难为无米之炊,我们首先需要获得一个堆转储文件.为了方便,本文采用的是 Sun JDK 6.通常来说,只要你设置了如下所示的 JVM 参数: -XX:+HeapDumpOnOutOf ...
- JVM性能分析 | 一次生产系统Full GC问题分析与排查总结
一次生产系统Full GC问题分析与排查总结 背景 最近某线上业务系统生产环境频频CPU使用率过低,频繁告警,通过重启可以缓解,但是过了一段时间又会继续预警,线上两个服务节点相继出现CPU资源紧张,导 ...
- 【J2EE性能分析篇】JVM参数对J2EE性能优化的影响
一切J2EE应用都是基于JVM的,那么对于JVM的设置和监控,成为J2EE应用程序性能分析和性能优化的必然手段.今天Sincky和大家交流该话题.这里以Tomcat环境为例,其它WEB服务器如Jbos ...
- 【转】JVM虚拟性能分析
JDK自带的JAVA性能分析工具.它已经在你的JDK bin目录里了,只要你使用的是JDK1.6 Update7之后的版本.点击一下jvisualvm.exe图标它就可以运行了. 这里是VisualV ...
- Java 性能分析工具 , 第 3 部分: Java Mission Control
引言 本文为 Java 性能分析工具系列文章第三篇,这里将介绍如何使用 Java 任务控制器 Java Mission Control 深入分析 Java 应用程序的性能,为程序开发人员在使用 Jav ...
- Java 性能分析工具 , 第 2 部分:Java 内置监控工具
引言 本文为 Java 性能分析工具系列文章第二篇,第一篇:操作系统工具.在本文中将介绍如何使用 Java 内置监控工具更加深入的了解 Java 应用程序和 JVM 本身.在 JDK 中有许多内置的工 ...
- 性能分析神器VisualVM
VisualVM 是一款免费的,集成了多个 JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优.这些功能包括生成和分析海量数据.跟踪内存泄漏.监控垃圾回 ...
- jvm性能监控与故障处理工具
jdk为我们提供了一系列的jvm性能监控和故障处理工具,在这里根据学习进度进行整理记录.便于之后查阅 1.jps 虚拟机进程工具 类似于Linux系统中的ps命令,用于查看虚拟机进程,常用的有以下功 ...
随机推荐
- struts2 异常页面乱码问题
在 struts.xml 或者 struts.properties 文件里添加 <constant name="struts.locale" value="zh_C ...
- 46. AngularJS所有版本下载
转自:https://www.cnblogs.com/best/tag/Angular/ 官网下载:https://angularjs.org/ AngularJS所有版本下载:https://cod ...
- 继承—people
public class People { private double height;//身高 private double weight;//体重 public double getHeight( ...
- 200 from memory cache / from disk cache / 304 Not Modified 区别
三者情况有什么区别和联系,什么情况下会发生200 from memory cache 或 200 from disk cache 或 304 Not Modified? 200 from memory ...
- 关于H5中 input消除默认,取消在手机上的点击高亮效果
input消除默认,代码如下 input{ -webkit-tap-highlight-color: rgba(255, 255, 255, 0); ...
- 比起 Windows,怎样解读 Linux 的文件系统与目录结构?
Linux 和 Windows 的文件系统有些不同,在学习使用 Linux 之前,若能够了解这些不同,会有助于后续学习. 本文先对 Windows 和 Linux 上面文件系统原理.组织概念进行区分, ...
- caffe(2) 数据层及参数
要运行caffe,需要先创建一个模型(model),如比较常用的Lenet,Alex等, 而一个模型由多个屋(layer)构成,每一屋又由许多参数组成.所有的参数都定义在caffe.proto这个文件 ...
- [BeiJing2009 WinterCamp]取石子游戏 Nim SG 函数
Code: #include<cstdio> #include<algorithm> #include<cstring> using namespace std; ...
- Linux 下安装 redis 详情
一:将redis 压缩包上传到 Linux usr/local下 (一):在local 下创建一个 redis 目录 (二):上传redis压缩包到此目录下. 二:Linux 进入 local目录下 ...
- CMSIS-RTOS 信号量
信号量Semaphores 和信号类似,信号量也是一种同步多个线程的方式,简单来讲,信号量就是装有一些令牌的容器.当一个线程在执行过程中,就可能遇到一个系统调用来获取信号量令牌,如果这个信号量包含多个 ...