如何通过mat从java内存dump中找到缓存对象中的所有字符串
mat简要介绍
引自官方说明,都是四级单词,不翻译了就:
The Eclipse Memory Analyzer is a fast and feature-rich Java heap analyzer that helps you find memory leaks and reduce
memory consumption.
Use the Memory Analyzer to analyze productive heap dumps with hundreds of millions of objects, quickly calculate the
retained sizes of objects, see who is preventing the Garbage Collector from collecting objects, run a report to
automatically extract leak suspects.
我们发现每个suggest机器的内存使用偏高,决定分析一份线上搜索服务的java heap的dump文件,。
生成java内存dump文件
标准做法,jmap dump,需要sudo权限,另外jmap指定的dump文件一定要是启动服务的用户可写,比如可以新创建一个文件夹
sudo mkdir /home/q/memdump sudo chown resin:resin /home/q/memdump
sudo -u resin /home/q/java/default/bin/jmap -dump:live,format=b,file=/home/q/memdump/memMap.20130527.hprof ${pid}
把dump文件拿到本地
把dump文件压缩下,否则会很大,scp到本地
安装mat
直接在eclipse里:
1.Help->Install New Software
2.输入update site: http://download.eclipse.org/mat/1.2/update-site/,然后一直next就行了,安装完重启eclipse
3.最好创建一个单独的workspace来放内存dump文件
把dump文件导入mat
1.打开eclipse,选择上一步你创建的存放内存dump文件的workspace,我本机上是~/mat
2.打开刚才拿到本地的dump文件,然后等着mat解析就完了,注意这时候你可能需要修改eclipse安装文件下的eclipse.ini,调整下eclipse的jvm参数(xms和xmx),把heap调大些,否则解析过程会报OOM
3.解析完后会生成一个Overview,我们一般会选择org.apache.catalina.loader.WebappClassLoader,作为分析top consumer的切入点,这是tomcat上web应用的classloader
4.单击饼图上org.apache.catalina.loader.WebappClassLoader的区域,会出现一个弹出菜单,选择List Objects->with incoming references,因为所有的web应用内的对象都会引用它们自己的class loader,也就是org.apache.catalina.loader.WebappClassLoader
5.得到如下所示列表,单击retained heap这个tab标签可以排序,选择按照占用内存的大小倒排序,得到了top memory consumers列表
定位缓存对象
我们关心的是top consumer里的RtTreeCache里,有多少重复房型,怎么得到的呢,follow the steps:
1.查看RtTreeCache对象的outgoing reference,因为我们需要看这个对象里面的属性,属性对象也就是RtTreeCache对象引用的对象,也就是outgoing reference
2.找到我们需要分析的数据在对象结构中的位置
3.可以看到我们要查找的目标是RtTreeCache对象下的所有HotelRtTree对象的rtReverseMap对象属性下的table数组内所有entry的key,我们接下来就看看怎么把这个冗长的关系转化成一个简单的OQL语句
写MAT OQL
OQL是MAT里的一个内嵌查询语言,它的官方描述很形象:
Memory Analyzer has a built-in object query language (OQL) that allows to query the heap dump with custom SQL-like queries. Just think of classes as tables, objects as rows, and fields as columns.
总结
jmap + mat是我们分析java内存的利器,而通过mat oql,我们可以从dump文件里提取出更多的类似于有多少内容相同的不同字符串对象等信息来帮助我们做技术决策。