文前说明
作为码农中的一员, 需要不断的学习, 我工作之余将一些分析总结和学习笔记写成博客与大家一起交流, 也希望采用这种方式记录自己的学习之旅.
本文仅供学习交流使用, 侵权必删.
1. 虚拟机堆转储快照分析工具(JVM Heap Analysis Tool)
jhat 命令和 jmap 命令搭配使用, 可以用来分析 jmap 生成的堆转储快照.
jhat 内置一个微型的 HTTP/html 服务器, 生成 dump 文件分析结果后, 可以在浏览器中查看.
可以通过 -J 方式, 将虚拟机参数传递给 jmap 调用的启动程序. 例如 -J-Xms48m.
1.1 命令格式
jhat [ options ] <heap-dump-file>
options 选项 (如果使用) 应紧跟在命令名之后.
heap-dump-file 要分析浏览的 Java 二进制堆转储文件. 对于包含多个堆转储的转储文件, 可以通过将 #<number> 附加到文件名 (即 "foo.hprof#3") 来指定文件中的哪个转储.
有多种获得 dump 堆转储快照文件的方式.
使用 jmap -dump 选项生成 dump 文件.
通过指定 -XX:+HeapDumpOnAutofMemoryError 虚拟机选项引发 OutOfMemoryError 时, 自动生成堆转储快照文件.
可以使用 jconsole 运行时获取堆转储:
可以使用 hprof 方式:
这个工具是实验性的, 在 JDK 未来版本中可能不可用.
选项 | 说明 |
---|---|
-stack false|true | 开关对象分配调用栈跟踪(tracking object allocation call stack)。 如果分配位置信息在堆转储中不可用,则必须将此标志设置为 false,默认值为 true。 |
-refs false|true | 开关对象引用跟踪(tracking of references to objects)。 默认值为 true。默认情况下,返回的指针是指向其他特定对象的对象,如反向链接或输入引用(referrers or incoming references),会统计 / 计算堆中的所有对象。 |
-port port-number | 设置 jhat HTTP server 的端口号。默认值 7000。 |
-exclude exclude-file | 指定对象查询时需要排除的数据成员列表文件(列出应从可访问对象查询中排除的数据成员的文件)。例如,如果文件列列出了 java.lang.String.value,那么当从某个特定对象 Object o 计算可达的对象列表时,引用路径涉及 java.lang.String.value 的都会被排除。 |
-baseline exclude-file | 指定一个基准堆转储(baseline heap dump)。在两个 heap dumps 中有相同 object ID 的对象会被标记为不是新的(marked as not being new)。其他对象被标记为新的(new)。在比较两个不同的堆转储时很有用。 |
-debug int | 设置 debug 级别。0 表示不输出调试信息。值越大则表示输出更详细的 debug 信息。 |
-version | 启动后只显示版本信息就退出。 |
-h | 打印帮助信息。 |
-help | 打印帮助信息。 |
1.2 执行样例
- [root@localhost ovirt]# sudo -u ovirt jhat -J-Xmx2048m /home/ovirt/dump.bin
- Reading from /home/ovirt/dump.bin...
- Dump file created Sat Feb 23 01:15:33 EST 2019
- Snapshot read, resolving...
- Resolving 7901861 objects...
- Chasing references, expect 1580 dots............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
- Eliminating duplicate references............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
- Snapshot resolved.
- Started HTTP server on port 7000
- Server is ready.
有时 dump 文件很大, 在启动时会报堆空间不足的错误, 可加参数 jhat -J-Xmx512m <heap dump file>, 这个内存大小可自行设置.
1.3 输出格式
可以通过 http://ip:7000/ 查看 jhat 输出.
jhat 输出
jhat 启动后显示的 HTML 页面中包含有.
显示出堆中所包含的所有的类(All Classes(including platform)).
从根集能引用到的对象(All Members of the Rootset).
显示平台包括的所有类的实例数量(Instance Counts for All Classes(including platform/excluding platform)).
堆实例的分布表(Heap Histogram).
Finalizer 摘要(Finalizer Summary).
执行对象查询语句(OQL).
一般查看堆异常情况主要看 Instance Counts for All Classes(excluding platform)平台外的所有对象信息和 Heap Histogram 以树状图形式展示堆情况.
观察是否大量应该被回收的对象在一直被引用或者是否有占用内存特别大的对象无法被回收.
1.4 OQL
jhat 支持预先设计的 OQL(对象查询语言)查询, 如果使用默认端口, 可以在 http://localhost:7000/oqlhelp/ 上获得 OQL 帮助.
OQL 是 SQL 类查询语言来查询 Java 堆.
OQL 允许筛选 / 选择从 Java 堆中获取的信息.
OQL 增加了更多的灵活性.
OQL 基于 JavaScript 表达式语言.
基本语法是: select <JavaScript expression to select>
- [ from [instanceof] <class name> <identifier>
- [ where <JavaScript boolean expression to filter> ] ]
class name 是 Java 类的完全限定名, 如: java.lang.String,java.util.ArrayList,[C 是 char 数组,[Ljava.io.File 是 java.io.File[].
类的完全限定名不足以唯一的辨识一个类, 因为不同的 ClassLoader 载入的相同的类, 它们在 Java 虚拟机中是不同类型的.
instanceof 表示也查询某一个类的子类, 如果不明确 instanceof, 则只精确查询 class name 指定的类.
from 和 where 子句都是可选的.
Java 域表示: obj.field_name.Java 数组表示: array[index].
来源: http://www.jianshu.com/p/1347cc8d79ee