分析Java堆Dump
堆转储是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.
参考: