使用Memory Analyse Tool分析内存溢出(非Eclipse插件)

Memory Analyse Tool是Java的dump文件分析工具,可以作为Eclipse的插件,也可以作为一个Windows下运行的软件单独使用,下面介绍一下MAT作为Windows软件的使用方式。

 

其实java的jvisualvm也可以用来分析dump文件,但是jvisualvm本身可以使用的系统内存不太好调,貌似需要.Net环境,我dump了一份1.5G的堆转储文件,用jvisualvm工具打不开,会报内存溢出,而MAT的内存可以在配置文件中调整。

 

一,MAT的下载安装

下载地址是:http://www.eclipse.org/mat/downloads.php


我选择的是Windows(x86_64),下载之后是个zip包,解压就直接可以使用


双击其中的MemoryAnalyzer.exe就可以运行此工具。

运行之后界面:



二,修改MAT可用内存

在MemoryAnalyzer.ini文件中可以修改MAT使用的内存大小


调整-Xmx属性,默认是1024M,这么设置没法打开1.5G的dump文件,我给改成了3024M。

 

三,dump文件获取

Linux环境下dump文件获取可以用以下命令:

jmap-dump:format=b,file=20170307.dump 16048

file后面的是自定义的文件名,最后的数字是进程的pid。

 

四,加载dump文件。

点击File-->Open Heap Dump,选择dump文件,MAT会加载并分析该dump文件,如果文件较大,可能需要一些时间。

开始分析时可以选择是否分析可能存在的问题,如果选择是,MAT会提供Problem Suspect,这个Problem Suspect如果你切到别的标签再切回来就没有了,可以通过点击Leak Suspects链接重新获得。

加载结束后的界面如下:


 

五,分析dump文件结果

不同的场景内存溢出的原因各不相同,我介绍一下我遇到这个场景

1,根据饼状图可以看到,进程一共占用了1.2G内存,有一个类(暗绿色)占了1G,这个类可能就是内存溢出的原因。

2,把鼠标移动到饼状图的暗绿色区域,在左侧会显示出该类的概要信息


3,左侧上方的Inspector栏显示了这个类的信息,可以看到这是NonRegisteringDriver类,在com.mysql.jdbc包下,后面还写着这个类的加载器,还有占用内存,这个NonRegisteringDriver是java在使用数据库的时候会用到的类,具体功能我以前也没研究过。

注意占用的内存实际上分成了两部分:112(shallow size)和1097869176(retained size)

shallow size这个表示类本身占用的内存大小,不包含其中引用的类占用的内存,而retained size代表包括其中引用类的内存,很小的类内存和很大的引用内存说明这个类里引用了特别占内存的对象。

4,左侧下方的Statics标签显示了这个类的静态属性,默认显示前25个,点击这一栏下方的+25 out of 28 displayed可以显示剩下的3个属性。

Class Hierarchy标签展示了这个类的继承关系:


5,点击右侧Actions栏的LeakSuspects按钮,MAT会提供Problem Suspect,如下图:


点击Details链接,可以看到关于这个类的很多信息,相当于一个小报表,比较长,分为几部分,我们重点关注第三部分,Accumulated Objects in Dominator Tree:


可以看到最顶层的就是NonRegisteringDriver类,经过层层引用,存在大量的com.mysql.jdbc.ByteArrayRow类,我不知道这个类是做什么用的,但看起来就是这个类的对象太多,导致内存占用过大。

点击其中任意一个com.mysql.jdbc.ByteArrayRow对象,比如我点了第一个,在左边的Attributes标签,会显示这个对象的属性:


然而根据这些属性我并不能知道这个类是干啥的,第一行的internalRowData属性,value值是一个byte类型的数组,可以在这一行上点击右键,选择go into,查看这个数组的详细信息:


从数组信息来看,有日期,有数字

另外,点击com.mysql.jdbc.ByteArrayRow类之后左边的Class Hierarchy标签,可以看到ByteArrayRow类的继承信息,


可以发现这个类是ResultSetRow类的子类,因此怀疑这个类实际上代表数据库查询出的ResultSet的一个元素。

ByteArrayRow类能发现的线索就这些,接下来可以点击他上层引用的类查看他们的Attributes标签,当看到com.mysql.jdbc.JDBC4PreparedStatement@ 0x78b85af40 这一行时,基本就已经确定了这次内存溢出的原因:


可以看到Attributes标签里面有一个originalSql属性,这个属性记录了这次查询的脚本,具体sql我就不贴了,其实就是一个全表查询,没有任何查询条件。

也就是说这次内存溢出的原因就是因为查询了数据库某个表全部的数据,把内存撑爆了。

 

另外我们可以看一下报表的倒数第二部分,Accumulated Objects by Class in Dominator Tree:


这一栏列出了引用最多的类,也就是之前看到的com.mysql.jdbc.ByteArrayRow类,有120多万个对象,我查了一下数据库,那个表里确实就是这么多数据,这也证明上面对内存溢出原因的判断是正确的。

 

至此,分析过程结束。

其实MAT这个工具支持的功能还有很多,上面介绍的只是一小部分功能,其他部分功能还可以继续挖掘。

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Joern是一个开源的代码静态分析工具,可以帮助开发人员快速进行代码安全性评估和漏洞检测。在Eclipse使用Joern,可以进一步方便地集成Joern的功能。 下面是在Eclipse使用Joern的步骤: 1. 首先,需要安装Eclipse IDE(集成开发环境)和Joern插件。可以从Eclipse官网下载Eclipse IDE,并从Joern的官方网站获取Joern插件的jar文件。 2. 打开Eclipse IDE,选择“Help”菜单,然后点击“Eclipse Marketplace”。在搜索栏中输入“Joern”,点击搜索按钮。 3. 在搜索结果中,找到Joern插件,点击“Go”按钮进行安装。安装完成后,需要重启Eclipse IDE。 4. 安装完毕后,在Eclipse的菜单栏中出现“Joern”选项,点击它可以进入Joern插件界面。 5. 在Joern插件界面中,可以选择分析的代码项目。点击“Add”按钮,选择要分析的代码项目所在的文件夹,并设置分析的语言类型。 6. 设置完项目后,可以在Joern插件界面的“Analyse”部分选择不同的分析方法,如漏洞检测、规则匹配等。根据需要进行适当的配置。 7. 完成配置后,点击“Analyze”按钮开始分析代码。分析结果将在Eclipse的Console视图中显示出来。 8. 可以根据分析结果进行代码改进或漏洞修复。可以使用Joern插件中的其他功能和工具,如可视化图形展示、查询分析结果等。 通过以上步骤,就可以在Eclipse使用Joern进行代码静态分析和漏洞检测。使用Joern可以帮助开发人员快速发现和修复代码中的安全问题,提高代码质量和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值