jmap查看内存-Memory Map for Java
-
jmap能够打印给定Java进程、核心文件或远程DEBUG服务器的共享对象内存映射或堆内存的详细信息
-
内存监控
-
分析对象内存
-heap 输出整个堆空间的详细信息,包括GC的使用、堆配置信息,以及内存的使用信息等
[root@hecs-82454 ~]# jmap -heap 25578 Attaching to process ID 25578, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.201-b09 using thread-local object allocation. Mark Sweep Compact GC Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 482344960 (460.0MB) NewSize = 10485760 (10.0MB) MaxNewSize = 160759808 (153.3125MB) OldSize = 20971520 (20.0MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: New Generation (Eden + 1 Survivor Space): capacity = 9502720 (9.0625MB) used = 6034800 (5.7552337646484375MB) free = 3467920 (3.3072662353515625MB) 63.506027747844826% used Eden Space: capacity = 8454144 (8.0625MB) used = 5128760 (4.891166687011719MB) free = 3325384 (3.1713333129882812MB) 60.665633327277135% used From Space: capacity = 1048576 (1.0MB) used = 906040 (0.8640670776367188MB) free = 142536 (0.13593292236328125MB) 86.40670776367188% used To Space: capacity = 1048576 (1.0MB) used = 0 (0.0MB) free = 1048576 (1.0MB) 0.0% used tenured generation: capacity = 20971520 (20.0MB) used = 11345584 (10.819992065429688MB) free = 9625936 (9.180007934570312MB) 54.09996032714844% used 11470 interned Strings occupying 978056 bytes.
都代表什么意思呢
Attaching to process ID 3764, 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) //采用Parallel GC Heap Configuration: MinHeapFreeRatio = 0 //JVM最小空闲比率 可由-XX:MinHeapFreeRatio=<n>参数设置, jvm heap 在使用率小于 n 时 ,heap 进行收缩 MaxHeapFreeRatio = 100 //JVM最大空闲比率 可由-XX:MaxHeapFreeRatio=<n>参数设置, jvm heap 在使用率大于 n 时 ,heap 进行扩张 MaxHeapSize = 2095054848 (1998.0MB) //JVM堆的最大大小 可由-XX:MaxHeapSize=<n>参数设置 NewSize = 44040192 (42.0MB) //JVM新生代的默认大小 可由-XX:NewSize=<n>参数设置 MaxNewSize = 698351616 (666.0MB) //JVM新生代的最大大小 可由-XX:MaxNewSize=<n>参数设置 OldSize = 88080384 (84.0MB) //JVM老生代的默认大小 可由-XX:OldSize=<n>参数设置 NewRatio = 2 //新生代:老生代(的大小)=1:2 可由-XX:NewRatio=<n>参数指定New Generation与Old Generation heap size的比例。 SurvivorRatio = 8 //survivor:eden = 1:8,即survivor space是新生代大小的1/(8+2)[因为有两个survivor区域] 可由-XX:SurvivorRatio=<n>参数设置 MetaspaceSize = 21807104 (20.796875MB) //元空间的默认大小,超过此值就会触发Full GC 可由-XX:MetaspaceSize=<n>参数设置 CompressedClassSpaceSize = 1073741824 (1024.0MB) //类指针压缩空间的默认大小 可由-XX:CompressedClassSpaceSize=<n>参数设置 MaxMetaspaceSize = 17592186044415 MB //元空间的最大大小 可由-XX:MaxMetaspaceSize=<n>参数设置 G1HeapRegionSize = 0 (0.0MB) //使用G1垃圾收集器的时候,堆被分割的大小 可由-XX:G1HeapRegionSize=<n>参数设置 Heap Usage: PS Young Generation //新生代区域分配情况 Eden Space: //Eden区域分配情况 capacity = 89653248 (85.5MB) used = 8946488 (8.532035827636719MB) free = 80706760 (76.96796417236328MB) 9.978989272089729% used From Space: //其中一个Survivor区域分配情况 capacity = 42467328 (40.5MB) used = 15497496 (14.779563903808594MB) free = 26969832 (25.720436096191406MB) 36.49275037977431% used To Space: //另一个Survivor区域分配情况 capacity = 42991616 (41.0MB) used = 0 (0.0MB) free = 42991616 (41.0MB) 0.0% used PS Old Generation //老生代区域分配情况 capacity = 154664960 (147.5MB) used = 98556712 (93.99100494384766MB) free = 56108248 (53.508995056152344MB) 63.722715216167906% used 1819 interned Strings occupying 163384 bytes.
-histo 输出堆空间中对象的统计信息,包括类、实例数量和合计容量
会打印出太多东西,所以我们需要查一下前X个,但是为什么不准确呢?
[root@hecs-82454 ~]# jmap -histo 25578 | head -n 30
num #instances #bytes class name
----------------------------------------------
1: 36277 3852128 [C
2: 6641 1860184 [I
3: 4205 1185840 [B
4: 33619 806856 java.lang.String
5: 8847 778536 java.lang.reflect.Method
6: 6234 688152 java.lang.Class
7: 20944 670208 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
8: 19979 639328 java.util.concurrent.ConcurrentHashMap$Node
9: 7481 420024 [Ljava.lang.Object;
10: 8484 339360 java.util.HashMap$KeyIterator
11: 8136 325440 java.util.LinkedHashMap$Entry
12: 3551 304832 [Ljava.util.HashMap$Node;
13: 5378 301168 java.util.concurrent.ConcurrentHashMap$KeyIterator
14: 119 251632 [Ljava.util.concurrent.ConcurrentHashMap$Node;
15: 11351 248896 [Ljava.lang.Class;
16: 6446 206272 java.util.HashMap$Node
17: 12664 202624 java.lang.Object
18: 3543 198408 java.util.LinkedHashMap
19: 5173 165536 java.util.ArrayList$Itr
20: 5753 138072 java.util.Collections$UnmodifiableCollection$1
21: 3415 136600 java.util.HashMap$ValueIterator
22: 1712 123264 java.lang.reflect.Field
23: 2404 115392 org.springframework.util.ConcurrentReferenceHashMap$SoftEntryReference
24: 2753 110120 java.util.TreeMap$Entry
25: 857 102840 org.springframework.boot.loader.jar.JarEntry
26: 1270 102304 [Ljava.util.WeakHashMap$Entry;
27: 4254 102096 java.util.concurrent.CopyOnWriteArrayList$COWIterator
其中#instances 为实例个数, #bytes为字节大小, class name 是对应的对象类型
B byte
C char
D double
F float
S short
I int
J long
Z boolean
[ 数组,如[I表示int[]
[L+类名 其他对象
查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象,如下:
jmap -histo:live pid
-dump 生成dump文件
Heap dump又称为堆转储文件,指一个Java进程在某个时间点的内存快照。
注:通常在写Heap dump文件之前,会执行一次Full GC,所以heap dump中保存的都是Full GC后留下的对象信息。
[root@hecs-82454 ~]# jmap -dump:format=b,file=/usr/local/1.hprof 25578
如果只想导出活着的对象
[root@hecs-82454 ~]# jmap -dump:live,format=b,file=/usr/local/1.hprof 25578
JVM中配置以下参数,当发生OOM时,将导出应用程序的当前堆快照。
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/3.hprof