前面通过jstat可以对JVM对的内存进行统计分析,而jmap可以获取到更加详细的内容,如:内存使用情况的汇总,对内存溢出的定位与分析。
1.查看内存使用情况
使用命令【jmap -heap 进程号】
E:北大青鸟Y2JVM>jmap -heap 17656
Attaching to process ID 17656, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 25.73-b02
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 = 4294901760 (4095.9375MB)
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 8847360 (8.4375MB)
used = 3589544 (3.4232559204101562MB)
free = 5257816 (5.014244079589844MB)
40.571922019675924% used
Eden Space:
capacity = 7929856 (7.5625MB)
used = 2672040 (2.5482559204101562MB)
free = 5257816 (5.014244079589844MB)
33.69594605501033% used
From Space:
capacity = 917504 (0.875MB)
used = 917504 (0.875MB)
free = 0 (0.0MB)
100.0% used
To Space:
capacity = 917504 (0.875MB)
used = 0 (0.0MB)
free = 917504 (0.875MB)
0.0% used
tenured generation:
capacity = 19415040 (18.515625MB)
used = 12128424 (11.566566467285156MB)
free = 7286616 (6.949058532714844MB)
62.46921973892405% used
12283 interned Strings occupying 1576968 bytes.
2.查看内存中对象数量及大小
使用命令【jmap -histo:live 进程号 | more】查看活跃对象
使用命令【jmap -histo 进程号 | more】查看所有对象
E:北大青鸟Y2JVM>jmap -histo:live 17656 | more
num #instances #bytes class name
----------------------------------------------
1: 29051 5802816 [C
2: 3618 1045824 [I
3: 27608 441728 java.lang.String
4: 779 386792 [B
5: 3229 316624 java.lang.Class
6: 3394 298672 java.lang.reflect.Method
7: 9984 239616 java.util.HashMap$Node
8: 3370 201096 [Ljava.lang.Object;
9: 757 119992 [Ljava.util.HashMap$Node;
10: 3047 73128 java.util.concurrent.ConcurrentHashMap$Node
11: 820 66880 [Ljava.lang.String;
12: 1057 42280 java.util.HashMap
13: 568 40896 java.lang.reflect.Constructor
14: 2207 38952 [Ljava.lang.Class;
15: 1572 37728 java.util.Hashtable$Entry
16: 1109 35488 java.util.LinkedHashMap$Entry
17: 1084 34688 java.util.TreeMap$Entry
18: 855 34200 org.apache.tomcat.util.modeler.AttributeInfo
19: 133 33672 [[C
20: 859 27488 java.lang.ref.SoftReference
21: 47 23568 [Ljava.util.concurrent.ConcurrentHashMap$Node;
22: 2529 20232 java.lang.Object
23: 594 19008 javax.management.MBeanAttributeInfo
24: 108 17608 [Ljava.util.Hashtable$Entry;
25: 710 17040 java.util.ArrayList
26: 565 13560 com.sun.org.apache.xerces.internal.xni.QName
3.将内存使用情况dump到文件中
有些时候我们需要将JVM当前内存中的情况dump到文件中,然后对它进行分析,jmap也是支持dump到文件中的;
使用命令【jmap -dump:format=b,file=E:北大青鸟Y2JVMdump.dat 进程号】
E:北大青鸟Y2JVM>jmap -dump:format=b,file=E:北大青鸟Y2JVMdump.dat 17656
Dumping heap to E:北大青鸟Y2JVMdump.dat ...
Heap dump file created
4.通过jhat对dump文件进行分析
我们将JVM的内存dump到文件中,这个文件是一个二进制文件,不方便查看,这时我们可以借助jhat工具进行查看;
使用命令【jhat -port 9999 E:北大青鸟Y2JVMdump.dat】
E:北大青鸟Y2JVM>jhat -port 9999 E:北大青鸟Y2JVMdump.dat
Reading from E:北大青鸟Y2JVMdump.dat...
Dump file created Tue Mar 03 14:46:51 CST 2020
Snapshot read, resolving...
Resolving 122032 objects...
Chasing references, expect 24 dots........................
Eliminating duplicate references........................
Snapshot resolved.
Started HTTP server on port 9999
Server is ready.
打开浏览器访问http://localhost:9999/
在最后面有QQL查询功能
点击下面选项
进入如下页面
输入下面语句查询字符串大于10000
select s from java.lang.String s where s.value.length >= 10000
点击Execute按钮,查询结果
5.通过MAT工具对dump文件进行分析
5.1 MAT工具介绍
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速,功能丰富的java heap分析工具,它可以帮助我们查找内存泄露和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过表现报表直观的查看可能造成这种结果的对象。
5.2 下载安装
下载地址:https://www.eclipse.org/mat/downloads.php
解压后得到的文件
5.3 使用
双击启动 MemoryAnalyzer.exe应用程序
Actions说明:
Histogram:列出内存中的对象,对象的个数以及大小
Dominator Tree:列出最大的对象以及其依赖存活的对象