给一个系统定位问题的时候,知识、经验是关键基础,数据是依据,工具是运用知识处理数据的手段。这里说的数据包括运行日志、异常堆栈、GC 日志、线程快照 (threaddump/javacore 文件) 堆转储快照 (headdump/hprof 文件) 等。经常使用适当的 JVM 监控和分析的工具可以加快我们分析数据、定位解决问题的速度。
1.JDK的命令行工具
jdk/bin 中命令行工具大多数是 jdk/lib/tools.jar 类库的一层薄封装,它们主要的功能代码是在 tools 类库中实现的。借助 tools.jar (Hotspot VM)类库里面的接口,我们可以直接在应用程序中实现功能强大的监控分析功能。
Sun JDK 监控和故障处理工具:
命令 | 说明 |
jps | JVM Process Status Tool,显示指定系统内所有的 HotSpot VM 进程 |
jstat | JVM Statistics Monitoring Tool,用于收集 HotSpot VM 各方面的运行数据 |
jinfo | Configuration Info for Java,显示 JVM 配置信息 |
jmap | Memory Map for Java,生成 JVM 的内存转储快照 (heapdump 文件) |
jhat | JVM Heap Dump Browser,用于分析 heapdump 文件,它会建立一个 HTTP/HTML 服务器,让用户可以在浏览器上查看分析结果 |
jstack | Stack Trace for Java,显示 JVM 的线程快照 |
2.Java监视与管理控制台JConsole
JDK 中除了提供大量的命令行工具外,还有两个功能强大的可视化工具: JConsole 和 VisualVM。JConsole 是一种基于 JMX 的可视化监视、管理工具,它管理部分的功能是针对 JMX MBean 进行管理,MBean 可以使用代码、中间件服务器的管理控制台或者所有符合 JMX 规范的软件进行访问。启动 JConsole 只需要在命令行运行 jconsole 即可。
页签名 | 对应命令 | 说明 |
概述 | 显示的是整个 JVM 主要运行数据的概览。 其中包括 “堆内存使用量”、“线程”、“类”、“CPU占用率” 4 种信息的曲线图。这些曲线图是后面 “内存”、“线程”、“类” 页签的信息汇总。 | |
内存 | jstat 命令 | 用于监视受收集器管理的 VM 内存 (Java 堆和永久代) 的变化趋势。 |
线程监控 | jstack 命令 | 遇到线程停顿时可以使用这个页签进行监控分析。线程长时间停顿的主要原因一般有: 等待外部资源 (数据库连接、网络资源、设备资源等);死循环;锁等待 (活锁和死锁)。 |
3.VisualVM多合一故障处理工具
VisualVM 是到目前为止随 JDK 发布的功能最强大的运行监视和故障处理程序,并且可以预见在未来一段时间内都是官方主力发展的 JVM 故障处理工具。VisualVM 除了运行监视、故障处理外,还提供了很多其他方面的功能,如性能分析 (Profiling),VisualVM 的性能分析功能甚至比 JProfiler、YourKit 等专业且收费的 Profiling 工具都不会逊色多少,而且 VisualVM 有一个很大的优点就是不需要被监视的程序基于特殊的 Agent 运行,因此它对应用程序性能的影响最小,使得它可以直接应用在生产环境中。
1.VisualVM兼容范围与插件安装
VisualVM 基于 NetBeans 平台开发,因此它一开始就具备了扩展功能的特性,通过插件扩展支持,VisualVM 可以做到:
1、显示 JVM 进程以及进程的配置、环境信息 (jps、jinfo)
2、监视应用程序的 CPU、GC、堆、方法区以及线程的信息 (jstat、jstack)
3、dump 以及分析堆转储快照 (jmap、jhat)
4、方法级的程序运行性能分析,找出被调用最多、运行时间最长的方法
5、离线程序快照: 收集程序的运行时配置、线程dump、内存dump等信息建立一个快照,可以将快照发送开发者处进行bug反馈
VisualVM 主要特性的兼容性列表如下:
| 特性 | JDK 1.4.2 | JDK 1.5 | JDK 1.6 local | JDK 1.6 remote |
|:---------- |:---------- |:---------- |:---------- |
| 运行环境信息 | v | v | v | v |
| 系统属性 | | | v | |
| 监视面板 | v | v | v | v |
| 线程面板 | | v | v | v |
| 性能监控 | | | v | |
| 堆、线程 Dump | | | v | |
| MBean 管理 | | v | v | v |
| JConsole 插件 | | v | v | v |
启动 VisualVM 只需要在命令行运行 jvisualvm 即可。
VisualVM 插件安装一般使用自动安装功能,在有网络的环境下,点击 工具 > 插件菜单,然后根据实际需要选择安装即可。安装完插件,选择一个需要监视的程序就进入程序的主界面了。
2.生成、浏览堆转储快照
在 VisualVM 中生成 dump 文件有两种方式:
1、应用程序 > 右键单击应用程序节点 > 然后选择 "堆Dump"
2、应用程序 > 双击应用程序节点打开标签 > 然后再 "监控" 标签中单击 "堆Dump"
生成了 dump 文件后,应用程序页签将在该堆的应用程序下增加一个以 [headdump] 开头的子节点。如果需要把 dump 文件保存或发送出去,要在[headdump] 节点上右键选择 “另存为” 菜单,否则当 VisualVM 关闭时,生成的 dump 文件会被当做临时文件删除掉。要打开一个已经存在的 dump 文件,通过文件菜单中的 “装入” 功能,选择硬盘上的 dump 文件即可。
堆 dump 页签说明如下:
页签 | 说明 |
摘要 | 可以看到应用程序 dump 时的运行时参数、System.getProperties() 的内容,线程堆栈等信息。 |
类 | 以类为统计口径统计类的实例数量、容量信息。 |
实例数 | 不能直接使用,因为不能确定用户想查看哪个类的实例,所以需要通过 “类” 面板进入,在 “类” 中选择一个关心的类后双击鼠标,即可在 “实例” 里面看见此类中 500 个实例的具体属性信息。 |
OQL控制台 | 这里是运行OQL查询语句的,同 jhat 中的 OQL 功能一样。 |
3.分析程序性能
在 “抽样器” 页签中,VisualVM 提供了程序运行期间方法级的 CPU 执行时间分析以及内存分析,做 Profiling 分析肯定会对程序运行性能有比较大的影响,所以一般不在生产环境中使用这项功能。
要开始分析,先选择 “CPU” 和 “内存” 按钮中的一个,然后切换到应用程序中对程序进行操作,VisualVM 会记录到这段时间中应用程序执行过的方法。如果是 CPU 分析,将会统计每个方法的执行次数、执行耗时;如果是内存分析,则会统计每个方法关联的对象数以及这些对象数所占的空间。分析结束后,点击 “停止” 按钮结束监控过程。
开发者分析自己的应用程序时,可根据实际业务的复杂度与方法的时间、调用次数做比较,找到最有优化价值的方法。