jmap命令的使用方法
jmap命令是一个可以输出所有内存中对象的工具。
环境
[root@localhost ~]$ hostnamectl
Static hostname: localhost.localdomain
Icon name: computer-vm
Chassis: vm
Machine ID: 68ac40d956e0497b905e9501b226a833
Boot ID: 2ea1d210069b47d8b8ee29499b69ab10
Virtualization: vmware
Operating System: Red Hat Enterprise Linux Server 7.6 (Maipo)
CPE OS Name: cpe:/o:redhat:enterprise_linux:7.6:GA:server
Kernel: Linux 3.10.0-957.el7.x86_64
Architecture: x86-64
[root@localhost ~]$ java -version
java version "1.8.0_241"
[root@localhost ~]$ whereis jps
jps: /usr/local/java/jdk1.8.0_241/bin/jps
[root@localhost ~]$ whereis jmap
jmap: /usr/local/java/jdk1.8.0_241/bin/jmap
jps -lm 查看java进程
[root@localhost ~]# jps -lm
28538 org.apache.catalina.startup.Bootstrap start
13480 org.apache.catalina.startup.Bootstrap start
31782 sun.tools.jps.Jps -lm
jmap pid 查看进程的内存映像信息
[tomcat@localhost ~]$ jmap 28538
Attaching to process ID 28538 , please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.241-b07
0x0000000000400000 8K /usr/local/java/jdk1.8.0_241/bin/java
0x00007f6cbd1a3000 66K /usr/lib64/libbz2.so.1.0.6
0x00007f6cbd3b3000 153K /usr/lib64/liblzma.so.5.2.2
0x00007f6cbd5d9000 88K /usr/lib64/libz.so.1.2.7
...
jmap -histo:live pid 显示堆中对象的统计信息
其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名
num #instances #bytes class name
----------------------------------------------
1: 1018645 134530712 [C
2: 362292 31881696 java.lang.reflect.Method
3: 1009550 24229200 java.lang.String
4: 541476 17327232 java.util.HashMap$Node
5: 171037 14842816 [Ljava.util.HashMap$Node;
6: 451511 14448352 java.util.concurrent.ConcurrentHashMap$Node
7: 346353 13854120 java.util.LinkedHashMap$Entry
8: 255572 12563576 [Ljava.lang.Object;
9: 178393 9990008 java.util.LinkedHashMap
10: 347429 8559664 [Ljava.lang.String;
11: 272754 6546096 java.util.ArrayList
12: 27651 5589312 [B
13: 47264 5584000 java.lang.Class
执行后,jvm会进行异常full gc,而执行full gc 必然会执行异常 minor gc
通过 jstat -gc pid
可以观察gc的执行次数
[tomcat@localhost ~]$ jstat -gc 21718
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
26624.0 25600.0 0.0 0.0 641536.0 100810.0 1398272.0 758420.1 311552.0 293303.5 35584.0 32421.5 3432 125.789 61 81.276 207.065
YGC:young gc 年轻代gc
YGCT:young gc 年轻代gc耗费时间
FGC:full gc 老年代gc
FGCT:full gc time 老年代gc耗费时间
jmap -heap pid 显示Java堆详细信息
[root@OA-TEST bin]# ./jmap -heap 28538
Attaching to process ID 28538, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.25-b02
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration: ##堆配置情况,也就是JVM参数配置的结果[平常说的tomcat配置JVM参数,就是在配置这些]
MinHeapFreeRatio = 0 ##最小堆使用比例
MaxHeapFreeRatio = 100 ##最大堆可用比例
MaxHeapSize = 4294967296 (4096.0MB) ##最大堆空间大小
NewSize = 357564416 (341.0MB) ##新生代分配大小
MaxNewSize = 1431306240 (1365.0MB) ##最大可新生代分配大小
OldSize = 716177408 (683.0MB) ##老年代大小
NewRatio = 2 ##新生代比例
SurvivorRatio = 8 ##新生代与suvivor的比例
PermSize = 134217728 (128.0MB) ##perm区 永久代大小
MaxPermSize = 134217728 (128.0MB) ##最大可分配perm区 也就是永久代大小
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage: ##堆使用情况【堆内存实际的使用情况】
PS Young Generation ##新生代(伊甸区Eden区 + 幸存区survior(1+2)空间)
Eden Space: ##伊甸区
capacity = 502267904 (479.0MB)
used = 353510928 (337.13429260253906MB)
free = 148756976 (141.86570739746094MB)
70.38294208821274% used
From Space: ##survior1区
capacity = 2621440 (2.5MB)
used = 2156832 (2.056915283203125MB)
free = 464608 (0.443084716796875MB)
82.276611328125% used
To Space: ##survior2 区
capacity = 23592960 (22.5MB)
used = 0 (0.0MB)
free = 23592960 (22.5MB)
0.0% used
PS Old Generation ##老年代使用情况
capacity = 746586112 (712.0MB)
used = 113048368 (107.81132507324219MB)
free = 633537744 (604.1886749267578MB)
15.142040038376711% used
55726 interned Strings occupying 5462160 bytes.
jmap -dump:format=b,file=heapdump.phrof pid 生成堆转储快照dump文件
这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用, 线上系统慎用。
[root@localhost ~]$ jmap -dump:format=b,file=heapdump.phrof 28538
[root@localhost ~]$ ll -h |grep phrof
-rw------- 1 root root 695M Apr 28 15:42 heapdump.phrof
tomcat退出生成dump
很多tomcat进程退出(或者进程假死),都是由于频繁的抛出OutOfMemeoryError导致的。
在tomcat启动参数中加入两个参数:
-XX:+HeapDumpOnOutOfMemoryError # JVM发生OOM时,自动生成DUMP文件
-XX:HeapDumpPath=/home/tomcat/oom.hprof # 生成DUMP文件的路径
分析dump文件
分析 dump文件可以使用 jvisualvm
(jdk1.8自带)
使用jvisualvm