笔记中躺了好久的文章,今天用到Mat时发现以前写的内容还算清晰,分享出来;
以下所举例使用的dump文件是针对以前使用的ignite库溢出时的dump文件;关于ignite的概念此处再也不叙述,本篇文章重点则在于Mat便可java
MAT是Memory Analyzer tool的缩写,是一种快速,功能丰富的Java堆分析工具,能帮助你查找内存泄漏和减小内存消耗。不少状况下,咱们须要处理测试提供的hprof文件,分析内存相关问题,那么MAT也绝对是不二之选。 Eclipse能够下载插件结合使用,也能够做为一个独立分析工具使用;下载地址:https://pan.baidu.com/s/1NDUR0E3WGrktm1qwoZHWfg
提取码:agxr ;不用谢,雷锋spring
打开Mat后File>OpenHeapDump打开一个对应的dump文件后,此时对应的打开后结果如图所示:apache
默认状况下打开该dump文件后,直接展现的就是一个Overview(概览)的页签,其中能够看到上面标注为(1,2)的地方所对应的图标与Overview页签中所对应的部分图标是类似的;若是你不当心关掉了Overview的页签,那么直接单击当前dump页签第一行导航栏的第一个 I字的图标便可,同理,若是此时想要打开Histogram,那么在不打开Overview的状况下,直接点击第一行导航栏的第二个图标便可;......数组
Overview页签下分别包含了:Actions,Reports,Step By Step 三大块功能;每一块功能下的子集所对应的做用分别是:dom
Actions:ssh
Histogram 列出每一个类所对应的对象个数,以及所占用的内存大小;工具
Dominator Tree 以占用总内存的百分比的方式来列举出全部的实例对象,注意这个地方是直接列举出的对应的对象而不是类,这个视图是用来发现大内存对象的测试
Top Consumers:按照类和包分组的方式展现出占用内存最大的一个对象插件
Duplicate Classes:检测由多个类加载器所加载的类信息(用来查找重复的类)线程
Reports:
Leak Suspects:经过MAT自动分析当前内存泄露的主要缘由
Top Components:Top组件,列出大于总堆1%的组件的报告
Step By Step:
上述全部被标注加粗的部分,是内存溢出dump分析时较为经常使用的功能点也是下面主要讲解的内容。
原创声明:做者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94
经过Histogram 列出每一个类所对应的对象个数,以及所占用的内存大小;
此处选中一个ClassName单击后,经过左上角Inspector能够看到当前类的回收状况,内存地址,等
补充解释:
字段一:表示当前类所对应的对象数量
字段二:Shallow Size是对象自己占据的内存的大小,不包含其引用的对象。对于常规对象(非数组)的Shallow Size由其成员变量的数量和类型来定,而数组的ShallowSize由数组类型和数组长度来决定,它为数组元素大小的总和;
字段三:Retained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和。(间接引用的含义:A->B->C,C就是间接引用) ,而且排除被GC Roots直接或者间接引用的对象;
关于红框内的Statics,Attributes,Classhierarchy,Value则分别表示当前类的静态变量,属性,当前类的层次结构图,以及当前类所对应的值Value;
注意:当前Histogram的列属性:ClassName,Objects,ShallowHeap,RetainedHeap这几个列属性下面都是有提供一个输入框,经过该输入框能够进行相关类的检索,好比:在ClassName下输入一个正则.quark.那么则获取到全部包路径为quark的类信息;
以占用总内存的百分比的方式来列举出全部的实例对象,能够用来发现大内存对象;
如上图所示:能够看到ConcurrentHashMap@0x60191cfa8这个对象占据了98.92%的堆大小,因此基本就能够判定,当前项目之因此会down机的主要缘由是,ConcurrentHashMap溢出所致使的问题;
那么当咱们须要查看,当前该ConcurrentHashMap@0x60191cfa8对象都引用了那些数据,以及当前该对象是被那几个对象所引用的,如何查看?
鼠标在当前所要查看的对象右键,点击List Objects能够看到分别提供了:with outgoing references(查看当前该对象的全部的引用信息) 和 with incoming references(查看当前该对象是被那几个对象所引用的) ;
原创声明:做者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94
经过MAT自动分析当前内存泄露的主要缘由
能够看到,当前MAT所给出内存泄露的主要缘由是:当前实例java.util.concurrent.ConcurrentHashMap被加载自system class loader,共占用了 98.92%的堆内存,这个实例被引用自org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl而且这个CacheObjectBinaryProcessorImpl这个对象是加载自LaunchedURLClassLoader这个类加载器;
而且还给出了所对应的主要关键词是:
java.util.concurrent.ConcurrentHashMap$Node[]
java.util.concurrent.ConcurrentHashMap
org.springframework.boot.loader.LaunchedURLClassLoader @ 0x6000a6860
基本上能够说是很详细了,一语中的,若是想要查看明细,能够直接点击detail,里面有更详细的说明,以下图所示:
上图分别说明了到该内存泄漏的对象的最快路径,也就是列出了当前ConcurrentHashMapConcurrentHashMap@0x60191cfa8这个对象所对应的被引用关系:能够看到当前引发内存泄漏的ConcurrentHashMap被CacheObjectBinaryProcessorImpl@0x60191cea8这个对象的metadataLocCache这个属性所引用,而CacheObjectBinaryProcessorImpl这个对象又被GridKernalContextImpl @ 0x601821bf8这个对象的cacheObjeProc这个属性所引用,以此递推;
除此以外,还有如下三个被隐藏的信息,点击便可查看明细:
Accumulated Objects in Dominator Tree (主控树中的累积对象),Accumulated Objects by Class in Dominator Tree(主控树中的按类累积对象 ,All Accumulated Objects by Class (按类列出全部的累积对象)
原创声明:做者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94
经过上述的解释应该对当前Overview下的功能使用已经有了一个大概的了解,须要注意的是,Histogram 以及Dominator Tree时所主要说起的Shallow Size以及Retained Size以及在所列出的对象上右键查看引用关系,GCROOTS,以及左上角所展现的属性明细等功能 是适用于全部的功能模块的,后续再也不赘述;
查看完上述关于Overview中的功能说明后,此处再来看一下Overview中不包含的一些功能
以下图所示,点击一级导航栏的第5个图标,能够用来查看当前进程dump时的全部线程的堆栈信息,经过分析下面所对应的堆栈信息,能够很快速的定位到对应的线程所执行的方法等层级关系,以此来定位对应的异常问题;
用于查询Java堆的类SQL查询语言
点击一级导航栏的第6个图标的下拉框下的 Heap Dump Overview,能够查看全局的内存占用信息
查看指定内存地址所对应的对象信息;
一、线程所引用对象溢出
二、静态属性对象溢出
线程栈所引用对象溢出的场景,以下:
Mat各功能内还有不少小的子功能,使用过程当中可逐步尝试,此处再也不赘述