jdk安装后会自带一些小工具,jmap命令(Java Memory Map)是其中之一。主要用于打印指定Java进程(或核心文件、远程调试服务器)的共享对象内存映射或堆内存细节。
option:
- no option: 查看进程的内存映像信息,类似 Solaris pmap 命令。
- heap: 显示Java堆详细信息
- histo[:live]: 显示堆中对象的统计信息
- clstats:打印类加载器信息
- finalizerinfo: 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
- dump:
:生成堆转储快照 - F: 当-dump没有响应时,使用-dump或者-histo参数. 在这个模式下,live子参数无效.
- help:打印帮助信息
- J
:指定传递给运行jmap的JVM的参数
例1:
命令:jmap -heap pid
描述:显示Java堆详细信息
打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和各内存区域内存使用信息
jmap -heap 5611
Attaching to process ID 5611, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 25.271-b09
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 268435456 (256.0MB)
NewSize = 5570560 (5.3125MB)
MaxNewSize = 89456640 (85.3125MB)
OldSize = 11206656 (10.6875MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 12582912 (12.0MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 4294963200 (4095.99609375MB)
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space): #年轻代
capacity = 5046272 (4.8125MB)
used = 1646832 (1.5705413818359375MB)
free = 3399440 (3.2419586181640625MB)
32.63462611607143% used
Eden Space: # 伊甸园区
capacity = 4521984 (4.3125MB)
used = 1614560 (1.539764404296875MB)
free = 2907424 (2.772735595703125MB)
35.70468183876812% used
From Space: #存活区
capacity = 524288 (0.5MB)
used = 32272 (0.0307769775390625MB)
free = 492016 (0.4692230224609375MB)
6.1553955078125% used
To Space: #存活区
capacity = 524288 (0.5MB)
used = 0 (0.0MB)
free = 524288 (0.5MB)
0.0% used
tenured generation: #老年代
capacity = 11206656 (10.6875MB)
used = 7409520 (7.0662689208984375MB)
free = 3797136 (3.6212310791015625MB)
66.11713610197368% used
5109 interned Strings occupying 397496 bytes.
例2
命令:jmap -histo:live pid
描述:显示堆中对象的统计信息
其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果指定了live子选项,则只计算活动的对象。
此命令常用来查看内存溢出
num #instances #bytes class name
----------------------------------------------
1: 2580 2986640 [B
2: 27304 2316368 [C
3: 7626 1577272 [I
4: 8714 418272 java.util.concurrent.ConcurrentHashMap$EntryIterator
5: 25061 400976 java.lang.String
6: 6301 296872 [Ljava.lang.Object;
7: 2981 284776 java.lang.Class
8: 8714 209136 java.util.concurrent.ConcurrentHashMap$MapEntry
9: 8679 208296 java.util.HashMap$Node
10: 4289 171560 java.util.HashMap
11: 3617 146984 [Ljava.util.HashMap$Node;
12: 1425 125400 java.lang.reflect.Method
13: 1676 120672 java.lang.reflect.Constructor
14: 1776 113664 java.util.regex.Matcher
15: 3480 83520 java.util.Hashtable$Entry
16: 3046 73104 java.util.concurrent.ConcurrentHashMap$Node
17: 687 71448 java.io.ObjectStreamClass
18: 723 63816 [Ljava.util.Hashtable$Entry;
19: 155 58280 java.lang.Thread
20: 1750 56000 java.io.ObjectStreamClass$WeakClassKey
例3:
命令:jmap -dump:format=b,file=heapdump.phrof pid
描述:生成堆转储快照dump文件。
以hprof二进制格式转储Java堆到指定filename的文件中。live子选项是可选的。如果指定了live子选项,堆中只有活动的对象会被转储。想要浏览heap dump,你可以使用jhat(Java堆分析工具)读取生成的文件。
这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用, 线上系统慎用。
[root@chenshifengdeLinuxServer ~]# jmap -dump:live,format=b,file=heap.bin 5611
Dumping heap to /root/heap.bin ...
Heap dump file created
然后会在当前目录生成一个heap.bin的二进制文件,可以使用jhat命令去解析
[root@chenshifengdeLinuxServer ~]# jhat -J-mx512 heap.bin
Error occurred during initialization of VM
Initial heap size set to a larger value than the maximum heap size
[root@chenshifengdeLinuxServer ~]# jhat -J-mx512m heap.bin
Reading from heap.bin...
Dump file created Sun Jun 06 21:40:36 CST 2021
Snapshot read, resolving...
Resolving 76088 objects...
Chasing references, expect 15 dots...............
Eliminating duplicate references...............
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
然后访问7000端口
最下面可以查看堆内存大小,和jmap -histo 一样