堆转储是Java虚拟机(JVM)堆中所有对象在某个时间点的快照。JVM为堆中所有类实例和数组的对象分配内存。当不再需要某个对象并且没有对该对象的引用时,垃圾回收器会回收堆内存。通过VisualVM检查堆,您可以找到对象的创建位置,并在源中找到对这些对象的引用。 如果 JVM 软件无法从堆中删除不需要的对象,则 VisualVM 可以帮助您找到该对象最近的垃圾回收根目录。
一、获取堆转储文件
方式一:jmap -dump:live,format=b,file=/app/logs/heapdump.hprof <PID>
方式二:java启动命令里配置参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/logs/heapdump.hprof
方式三:使用JConsole(MBean)、VisualVM工具通过界面操作生成。
VisualVM可以打开以.hprof格式保存的堆转储. 本文使用VisualVM 2.1.7版本。
二、VisualVM2.1.7 浏览分析堆转储
1、摘要视图
打开堆转储时,默认情况下,VisualVM 会显示“摘要”视图。 “摘要”视图显示执行堆转储的运行环境和其他系统属性。
2、对象视图
“类”视图显示包、类、实例列表以及对应数量和百分比。
可以通过右键单击名称并选择“在新tab显示”来查看特定类的实例列表。
可以通过单击列标题对结果的显示方式进行排序。
可以使用列表下方的筛选器按名称筛选类或限制显示的结果 通过右键单击类名并选择“仅显示子类”来添加类的子类。
还可以查看字段、引用、GC Root、继承关系。可以通过单击列标题对结果的显示方式进行排序。
可以使用列表下方的筛选器按名称筛选类或限制显示的结果 通过右键单击类名并选择“仅显示子类”来添加类的子类。
3、线程视图
“线程”视图各个线程下对应对象实例内存大小。
4、OQL Console
OQL语言查询视图。
5、R Console
R语言查询视图
三、分析堆Dump思路
1、一般先用命令 看一下内存里占比较高的异常类
命令:看一下按照类实例占内存大小排序前100个类
[wjy@node101 ~]# jmap -histo 4097 |head -n 100
num #instances #bytes class name
----------------------------------------------
1: 1522828 117688952 [C
2: 124088 53254840 [I
3: 123954 36162376 [B
4: 1127285 27054840 java.lang.String
5: 288726 25407888 java.lang.reflect.Method
6: 338276 17705432 [Ljava.lang.Object;
7: 446427 14285664 java.util.concurrent.ConcurrentHashMap$Node
8: 404112 12901888 [Ljava.lang.String;
9: 344976 11039232 java.util.HashMap$Node
10: 235201 9408040 java.util.LinkedHashMap$Entry
11: 95002 9138648 [Ljava.util.HashMap$Node;
12: 110706 6199536 java.util.LinkedHashMap
13: 83599 6019128 java.lang.reflect.Field
14: 245093 5882232 java.util.ArrayList
15: 3672 5476080 [Ljava.util.concurrent.ConcurrentHashMap$Node;
16: 240320 5202928 [Ljava.lang.Class;
17: 102795 4934160 java.util.StringTokenizer
18: 87123 4181904 org.aspectj.weaver.reflect.ShadowMatchImpl
19: 141683 4062296 [Z
20: 29218 3713216 java.lang.Class
21: 134206 3220944 org.springframework.core.MethodClassKey
22: 36108 2888640 nonapi.io.github.classgraph.fastzipfilereader.FastZipEntry
23: 87123 2787936 org.aspectj.weaver.patterns.ExposedState
24: 53957 2589936 java.util.HashMap
25: 65834 2106688 java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
26: 18186 1891344 sun.net.www.protocol.file.FileURLConnection
27: 117774 1884384 java.lang.Object
28: 73044 1753056 org.springframework.cglib.core.Signature
29: 72600 1742392 [Lorg.aspectj.weaver.ast.Var;
30: 52448 1678336 java.util.ArrayList$Itr
31: 28354 1587824 org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
32: 63122 1514928 java.lang.StringBuilder
33: 62712 1505088 org.hibernate.validator.internal.properties.Signature
34: 2000 1344000 io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueue
35: 32745 1309800 java.util.TreeMap$Entry
36: 24707 1185936 org.springframework.util.ConcurrentReferenceHashMap$SoftEntryReference
37: 36486 1167552 org.springframework.cglib.proxy.MethodProxy
38: 36423 1165536 org.springframework.cglib.proxy.MethodProxy$CreateInfo
39: 18726 1048656 org.springframework.core.annotation.TypeMappedAnnotation
40: 40895 981480 org.springframework.aop.framework.AdvisedSupport$MethodCacheKey
41: 19513 959272 [[Ljava.lang.String;
42: 23196 927840 org.hibernate.validator.internal.metadata.aggregated.PropertyMetaData
43: 18576 891648 org.springframework.web.util.pattern.PathPattern$MatchingContext
44: 10879 870320 java.lang.reflect.Constructor
45: 11281 820520 [Ljava.lang.reflect.Method;
46: 1350 756000 org.hibernate.persister.entity.SingleTableEntityPersister
47: 15167 728016 org.springframework.core.ResolvableType
48: 21659 693088 java.util.TreeMap$KeyIterator
49: 41854 669664 java.util.LinkedHashSet
50: 13638 654624 org.hibernate.metamodel.model.domain.internal.SingularAttributeImpl
51: 19310 617920 java.io.File
52: 9491 607424 java.util.regex.Matcher
53: 13974 558960 org.hibernate.tuple.entity.EntityBasedBasicAttribute
54: 8517 545088 java.util.concurrent.ConcurrentHashMap
55: 11293 542064 java.util.concurrent.ConcurrentHashMap$TreeNode
56: 16376 524032 java.lang.ref.WeakReference
57: 15984 511488 javax.servlet.ServletRequestAttributeEvent
58: 6710 483120 java.util.regex.Pattern
59: 20031 480744 sun.net.www.MessageHeader
60: 12004 480160 java.lang.ref.SoftReference
61: 14394 460608 org.hibernate.property.access.spi.GetterFieldImpl
62: 14394 460608 org.hibernate.property.access.spi.SetterFieldImpl
63: 7090 453760 java.net.URL
64: 2574 453024 org.springframework.beans.factory.support.RootBeanDefinition
65: 9376 450048 java.util.TreeMap
66: 14040 449280 org.hibernate.tuple.BaselineAttributeInformation
67: 7892 441952 org.springframework.core.type.classreading.SimpleAnnotationMetadata
68: 18239 437736 org.springframework.util.ConcurrentReferenceHashMap$Entry
69: 18016 432384 java.util.Collections$UnmodifiableRandomAccessList
70: 17577 421848 sun.reflect.annotation.AnnotationInvocationHandler
71: 17542 421008 com.ulisesbocchio.jasyptspringboot.caching.CachingDelegateEncryptablePropertySource$$Lambda$339/183304529
72: 17542 421008 org.springframework.cache.concurrent.ConcurrentMapCache$$Lambda$340/521331027
73: 8647 415056 java.nio.HeapCharBuffer
74: 12307 393824 java.util.regex.Pattern$Curly
75: 16302 391248 com.fasterxml.classmate.members.RawMethod
76: 6884 385504 java.lang.Class$ReflectionData
77: 11966 382912 java.util.LinkedHashMap$LinkedKeyIterator
78: 6541 366296 [Ljava.util.regex.Pattern$GroupHead;
79: 15252 366048 org.hibernate.metamodel.model.domain.internal.BasicTypeImpl
80: 15252 366048 org.hibernate.metamodel.model.domain.internal.SingularAttributeImpl$DelayedKeyTypeAccess
81: 5416 352592 [S
82: 8811 352440 org.springframework.core.type.classreading.SimpleMethodMetadata
83: 10932 349824 java.util.concurrent.locks.ReentrantLock$NonfairSync
84: 8744 349760 java.util.WeakHashMap$Entry
85: 5979 334824 java.util.stream.ReferencePipeline$Head
86: 5920 331520 sun.nio.cs.UTF_8$Encoder
87: 13213 331176 [Ljava.lang.annotation.Annotation;
88: 20658 330528 java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry
89: 13133 320304 [Lorg.springframework.core.annotation.AnnotationTypeMappings;
90: 3736 318520 [J
91: 2601 312120 org.springframework.boot.loader.jar.JarEntry
92: 12615 307848 [Lorg.springframework.core.annotation.MergedAnnotation;
93: 12615 302760 org.springframework.core.annotation.MergedAnnotationsCollection
94: 12019 282776 [Ljava.lang.reflect.Type;
95: 8811 281952 org.springframework.core.type.classreading.SimpleMethodMetadataReadingVisitor$Source
96: 1521 279864 com.fasterxml.jackson.core.json.ReaderBasedJsonParser
97: 6972 278880 org.springframework.web.util.pattern.LiteralPathElement
2、如果存在出现内存占比较高的类,
则使用命令jmap -dump:format=b,file=/app/logs/heapdump.hprof <PID> 生成堆Dump文件;
然后下载到本地,使用VisualVM导入 重点分析这个类的引用代码情况;
分析这个类的内存占比为什么这么高。
四、MAT
上文介绍VisualVM分析堆转储过程,但是实际工作种用MAT的还是比较多,MAT功能强大,提供更多的工具从不同的角度全面分析Dump.
参考:
VisualVM -Browsing a Heap Dump
学习技术不是用来写HelloWorld和Demo的,而是要用来解决线上系统的真实问题的.