jmap 命令
1. 获取heap dump文件
jmap -dump:live,format=b,file=h.hprof [pid] # 会触发gc,只转存存活对象
或者
jmap -dump:format=b,file=h3.hprof [pid]
jmap的作用并不仅仅是为了获取堆转储快照,它还可以查询finalize执行队列、Java堆和方法区的详细信息,如空间使用率、当前用的是哪种收集器等。
jmap工具的主要选项如下:
选项 | 描述 |
---|---|
-dump | 用于生成JVM的heap快照文件,命令格式:jmap -dump[:live],format=b,file=<filename.prof> <pid> ,其中live可选,表示是否只导出存活对象,如果指定会触发GC。 |
-finalizernfo | 该命令只能在类Unix环境下运行,用于显示在F-Queue中等待Finalizer线程执行finalize方法的对象。 |
-heap | 该命令只能在类Unix环境下运行,用于显示当前Java heap的详细信息,例如使用那种回收器,详细的参数,分代情况等。 |
-histo | 显示堆中对象统计信息,包括对象示例、类、合计容量信息。 |
-F | 当JVM对-dump不响应时可以使用该参数强制生成heap dump快照文件。 |
如下是在mac中执行–help命令的帮助文档
jdk8
$ jmap --help
Usage:
jmap [option] <pid>
(to connect to running process)
jmap [option] <executable <core>
(to connect to a core file)
jmap [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)
where <option> is one of:
<none> to print same info as Solaris pmap
-heap to print java heap summary
-histo[:live] to print histogram of java object heap; if the "live"
suboption is specified, only count live objects
-clstats to print class loader statistics
-finalizerinfo to print information on objects awaiting finalization
-dump:<dump-options> to dump java heap in hprof binary format
dump-options:
live dump only live objects; if not specified,
all objects in the heap are dumped.
format=b binary format
file=<file> dump heap to <file>
Example: jmap -dump:live,format=b,file=heap.bin <pid>
-F force. Use with -dump:<dump-options> <pid> or -histo
to force a heap dump or histogram when <pid> does not
respond. The "live" suboption is not supported
in this mode.
-h | -help to print this help message
-J<flag> to pass <flag> directly to the runtime system
jdk11
$ jmap --help
Usage:
jmap -clstats <pid>
to connect to running process and print class loader statistics
jmap -finalizerinfo <pid>
to connect to running process and print information on objects awaiting finalization
jmap -histo[:live] <pid>
to connect to running process and print histogram of java object heap
if the "live" suboption is specified, only count live objects
jmap -dump:<dump-options> <pid>
to connect to running process and dump java heap
jmap -? -h --help
to print this help message
dump-options:
live dump only live objects; if not specified,
all objects in the heap are dumped.
format=b binary format
file=<file> dump heap to <file>
Example: jmap -dump:live,format=b,file=heap.bin <pid>
2. jmap -heap
如果需要在jdk11中查看类似在jdk8中的jmap -heap <pid>
的内容,需要执行jhsdb jmap --heap --pid <pid>
执行如下:
$ jhsdb jmap --heap --pid 10950
Attaching to process ID 10950, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 11.0.12+8-LTS-237
using thread-local object allocation.
Garbage-First (G1) GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 134217728 (128.0MB)
NewSize = 1363144 (1.2999954223632812MB)
MaxNewSize = 79691776 (76.0MB)
OldSize = 5452592 (5.1999969482421875MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 1048576 (1.0MB)
Heap Usage:
G1 Heap:
regions = 128
capacity = 134217728 (128.0MB)
used = 100663296 (96.0MB)
free = 33554432 (32.0MB)
75.0% used
G1 Young Generation:
Eden Space:
regions = 14
capacity = 22020096 (21.0MB)
used = 14680064 (14.0MB)
free = 7340032 (7.0MB)
66.66666666666667% used
Survivor Space:
regions = 4
capacity = 4194304 (4.0MB)
used = 4194304 (4.0MB)
free = 0 (0.0MB)
100.0% used
G1 Old Generation:
regions = 78
capacity = 108003328 (103.0MB)
used = 81788928 (78.0MB)
free = 26214400 (25.0MB)
75.72815533980582% used
3. jmap -histo
使用jmap -histo <pid>
可以统计出当前JVM进程中的对象量,如下:
$ jmap -histo 10950
num #instances #bytes class name (module)
-------------------------------------------------------
1: 1127420 38934176 [B (java.base@11.0.12)
2: 1007019 24168456 java.lang.String (java.base@11.0.12)
3: 1000660 24015840 java.util.LinkedList$Node (java.base@11.0.12)
4: 119709 5746032 java.nio.HeapCharBuffer (java.base@11.0.12)
5: 521 1449296 [I (java.base@11.0.12)
6: 59856 1436544 java.lang.StringBuilder (java.base@11.0.12)
7: 1050 128360 java.lang.Class (java.base@11.0.12)
8: 3163 101216 java.util.HashMap$Node (java.base@11.0.12)
9: 884 87152 [Ljava.lang.Object; (java.base@11.0.12)
10: 387 55208 [Ljava.util.HashMap$Node; (java.base@11.0.12)
11: 12 50104 [C (java.base@11.0.12)
12: 1156 46240 java.util.LinkedHashMap$Entry (java.base@11.0.12)
13: 1177 37664 java.util.concurrent.ConcurrentHashMap$Node (java.base@11.0.12)
...
jhat 命令
在使用jmap或者其他方式,获取到java heap的dump文件之后,对文件内容进行分析
jhat是一个用来分析java的堆情况的命令。jhat命令将dump文件转成html的形式,然后通过http访问可以查看堆情况。
jdk11查看帮助文档:
$ jhat -h
Usage: jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>
-J<flag> Pass <flag> directly to the runtime system. For
example, -J-mx512m to use a maximum heap size of 512MB
-stack false: Turn off tracking object allocation call stack.
-refs false: Turn off tracking of references to objects
-port <port>: Set the port for the HTTP server. Defaults to 7000
-exclude <file>: Specify a file that lists data members that should
be excluded from the reachableFrom query.
-baseline <file>: Specify a baseline object dump. Objects in
both heap dumps with the same ID and same class will
be marked as not being "new".
-debug <int>: Set debug level.
0: No debug output
1: Debug hprof file parsing
2: Debug hprof file parsing, no server
-version Report version number
-h|-help Print this help and exit
<file> The file to read
For a dump file that contains multiple heap dumps,
you may specify which dump in the file
by appending "#<number>" to the file name, i.e. "foo.hprof#3".
All boolean options default to "true"
选项 | 描述 |
---|---|
-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 | 指定对象查询时需要排除的数据成员列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 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 | 启动后只显示版本信息就退出 |
-J< flag > | 因为 jhat 命令实际上会启动一个JVM来执行, 通过 -J 可以在启动JVM时传入一些启动参数. 例如, -J-Xmx512m 则指定运行 jhat 的Java虚拟机使用的最大堆内存为 512 MB. 如果需要使用多个JVM启动参数,则传入多个 -Jxxxxxx. |
运行命令jhap <dump_file>
:
$ jhat java_pid10301.hprof
Reading from Desktop/java_pid10301.hprof...
Dump file created Sat Dec 18 10:47:28 CST 2021
Snapshot read, resolving...
Resolving 4830119 objects...
Chasing references, expect 966 dots.................
Eliminating duplicate references................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
然后使用浏览器访问本地7000端口:
页面功能简介
一般查看堆异常情况主要看这个两个部分:
1、Show instance counts for all classes (excluding platform),平台外的所有对象信息。
2、Show heap histogram 以树状图形式展示堆情况。
具体排查时需要结合代码,观察是否大量应该被回收的对象在一直被引用或者是否有占用内存特别大的对象无法被回收。
OQL
jhat还提供了一种对象查询语言(Object Query Language),OQL有点类似SQL,可以用来查询。
OQL语句的执行页面: http://localhost:7000/oql/
OQL帮助信息页面为: http://localhost:7000/oqlhelp/
mat 工具
安装忽略
MAT进行OOM分析,多点点就清楚了