JVM之jmap的使用以及内存溢出分析
基本概念
jmap
(Java Virtual Machine Memory Map)是JDK提供的一个可以生成Java虚拟机的堆转储快照dump文件的命令行工具。除此以外,jmap命令还可以查看finalize执行队列、Java堆和方法区的详细信息,比如空间使用率、当前使用的什么垃圾回收器、分代情况等等。
之前写过通过jstat
可以对jvm堆的内存进行统计分析,而jmap
可以获取到更加详细的内容,如:内存使用情况的汇总、对内存溢出的定位与分析。
还有几种方式获取dump文件:
- 使用JVM参数选项-XX:+HeapDumpOnOutOfMemoryError参数,可以让虚拟机在OOM异常出现之后自动生成dump文件,通过-XX:HeapDumpPath=path 设置dump文件路径(有时候dump文件比较大的时候可能无法自动导出,这时候就需要使用jmap -dump手动导出了);
- 通过-XX:+HeapDumpOnCtrlBreak参数则可以使用[Ctrl]+[Break]键让虚拟机生成dump文件;
- 或者在Linux系统下通过Kill -3命令发送进程退出信号,也能拿到dump文件。
jhat
是java虚拟机自带的一种虚拟机堆转储快照分析工具。jhat
命令与jmap
命令搭配使用,用于分析jmap生成的heap dump文件(堆转储快照)。jhat内置了一个微型的HTTP/HTML服务器,对生成的dump文件分析后,可以在浏览器中查看分析结果。
使用jhat命令,会启动一个http服务,默认端口7000。
注:jhat
命令在JDK9、JDK10中已经被删除,官方建议用VisualVM
代替。
查看内存使用情况
C:\Users\zjq>jmap -heap 21180
Attaching to process ID 21180, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.171-b11
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration: #堆内存配置
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 4263510016 (4066.0MB)
NewSize = 89128960 (85.0MB)
MaxNewSize = 1420820480 (1355.0MB)
OldSize = 179306496 (171.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage: #堆内存使用情况
PS Young Generation #年轻代
Eden Space:
capacity = 266338304 (254.0MB)
used = 182061632 (173.62750244140625MB)
free = 84276672 (80.37249755859375MB)
68.35728442575049% used
From Space:
capacity = 28835840 (27.5MB)
used = 0 (0.0MB)
free = 28835840 (27.5MB)
0.0% used
To Space:
capacity = 30932992 (29.5MB)
used = 0 (0.0MB)
free = 30932992 (29.5MB)
0.0% used
PS Old Generation #老年代
capacity = 118489088 (113.0MB)
used = 27846344 (26.55634307861328MB)
free = 90642744 (86.44365692138672MB)
23.501188565144496% used
14751 interned Strings occupying 1962648 bytes.
查看内存中对象数量及大小
查看所有对象,包括活跃以及非活跃的
jmap ‐histo | more
查看活跃对象
jmap ‐histo:live | more
C:\Users\dell>jmap -histo:live 21180 | more
num #instances #bytes class name
----------------------------------------------
1: 44820 9393464 [C
2: 2280 3998688 [B
3: 4834 1915136 [I
4: 42374 1016976 java.lang.String
5: 21879 700128 java.util.HashMap$Node
6: 7375 448040 [Ljava.lang.Object;
7: 3718 420672 java.lang.Class
8: 1227 362648 [Ljava.util.HashMap$Node;
9: 7387 236384 java.util.concurrent.ConcurrentHashMap$Node
10: 2382 152448 java.net.URL
11: 1269 112128 [Ljava.lang.String;
12: 4176 100224 java.util.ArrayList
13: 2072 99456 java.util.HashMap
14: 2033 97584 org.apache.tomcat.util.digester.CallMethodRule
15: 78 96192 [Ljava.util.concurrent.ConcurrentHashMap$Node;
16: 5694 91104 java.lang.Object
17: 2216 88640 java.util.LinkedHashMap$Entry
18: 2425 77600 com.sun.org.apache.xerces.internal.xni.QName
19: 2806 63400 [Ljava.lang.Class;
20: 1282 61536 org.apache.catalina.loader.ResourceEntry
21: 100 54784 [Ljava.util.WeakHashMap$Entry;
22: 1658 53056 java.util.Hashtable$Entry
23: 654 52320 java.lang.reflect.Constructor
24: 555 48840 java.lang.reflect.Method
25: 1131 45240 java.lang.ref.SoftReference
26: 1352 43264 java.lang.ref.WeakReference
27: 878 42144 org.apache.tomcat.util.modeler.AttributeInfo
28: 1021 40840 java.util.TreeMap$Entry
29: 1601 38424 java.util.LinkedList$Node
30: 133 33672 [[C
31: 421 30312 java.util.logging.Logger
-- More --
#对象说明
B byte
C char
D double
F float
I int
J long
Z boolean
[ 数组,如[I表示int[] [L+类名 其他对象
将内存使用情况dump到文件中
有些时候我们需要将jvm当前内存中的情况dump到文件中,然后对它进行分析,jmap也是支持dump到文件中的。
#用法:
jmap -dump:format=b,file=dumpFileName <pid>
#示例
C:\Users\zjq>jmap -dump:format=b,file=E:\dump.dat 21180
Dumping heap to E:\dump.dat ...
Heap dump file created
说明:
live
参数是可选的,如果指定,则只转储堆中的活动对象;如果没有指定,则转储堆中的所有对象。format=b
表示以hprof二进制格式转储Java堆的内存。file=<filename>
用于指定快照dump文件的文件名。
可以看到已经在E盘下生成了dump.dat的文件。
通过jhat对dump文件进行分析
我们将jvm的内存dump到文件中,这个文件是一个二进制的文件,不方便查看,这时我们可以借助于jhat
工具进行查看。
#用法:
jhat ‐port <port> <file>
#示例:
C:\Users\dell>jhat -port 8080 E:\dump.dat
Reading from E:\dump.dat...
Dump file created Sun Jul 25 20:46:58 CST 2021
Snapshot read, resolving...
Resolving 584829 objects...
Chasing references, expect 116 dots....................................................................................................................
Eliminating duplicate references....................................................................................................................
Snapshot resolved.
Started HTTP server on port 8080
Server is ready.
打开浏览器进行访问:http://localhost:8080/
在最后面有OQL查询功能。
- 点赞
- 收藏
- 关注作者
评论(0)