java内存占用分析_Java程序内存分析:使用mat工具分析内存占用

MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如 Sun, HP, SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的 PHD 堆存储文件等都能被很好的解析。下面来看看要怎么做呢,也许对你有用。官方文档:http://help.eclipse.org/luna/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html

造成OutOfMemoryError原因一般有2种:

1、内存泄露,对象已经死了,无法通过垃圾收集器进行自动回收,通过找出泄露的代码位置和原因,才好确定解决方案;

2、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不足,检查堆设置大小(-Xmx与-Xms),检查代码是否存在对象生命周期太长、持有状态时间过长的情况。

1. 用jmap生成堆信息

31f119189e4bccdb0b5b3e554f71708b.png

这样在E盘的jmap文件夹里会有一个map.bin的堆信息文件

2. 将堆信息导入到mat中分析

69e36bbc66fdb22626fabf0ec6389e13.png

3. 生成分析报告

mat可以为我们生成多个报告:

396bfeca87f4fef92018688471c9b453.png    6039514b79d8da0dbc6c9467676d79d2.png

62713b9861eb21c86e27422865c0d02b.png    5d41d8ce7656d12b71faeeadd55f4c35.png

下面来看看生成的这些数据对我们有什么帮助

1f8f2cfca3a9cfbb5c8460b396f3a500.png

从上图可以看到它的大部分功能,在饼图上,你会发现转储的大小和数量的类,对象和类加载器。

正确的下面,饼图给出了一个印象最大的对象转储。移动你的鼠标一片看到对象中的对象的细节检查在左边。下面的Action标签中:

Histogram可以列出内存中的对象,对象的个数以及大小。

Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。

Top consumers通过图形列出最大的object。

Leak Suspects通过MA自动分析泄漏的原因。

Histogram

efc2911db82dc4eb55931400d0217af9.png

Class Name : 类名称,java类名

Objects : 类的对象的数量,这个对象被创建了多少个

Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用

Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的总和

一般来说,Shallow Heap堆中的对象是它的大小和保留内存大小相同的对象是堆内存的数量时,将释放对象被垃圾收集。

保留设置一组主要的对象,例如一个特定类的所有对象,或所有对象的一个特定的类装入器装入的类或者只是一群任意对象,是释放的组对象如果所有对象的主要设置变得难以接近的。保留设置包括这些对象以及所有其他对象只能通过这些对象。保留大小是总堆大小中包含的所有对象的保留。摘自eclipse

96a7e79ea705a87a5f865317e406c5bf.png

这儿借助工具提供的regex正则搜索一下我们自己的类,排序后看看哪些相对是占用比较大的。

aaaf8922875979b9e2eaa9c0dcc4260c.png

左边可以看到类的详细使用,比如所属包,父类是谁,所属的类加载器,内存地址,占用大小和回收情况等

1fb8c4bc3c7d42fa9a1c7ef5f811ccf4.png

这儿有个工具可以根据自己的需求分组查找,默认根据class分组,类似我们sql里的group by了~~

0eb07b1e00cabe8a32d612097a5e885b.png

这里可以看到上面3个选项,分别生成overview、leak suspects、top components数据,但是这儿生成的不是图表,如果要看图表在5a4bc6447405cf6eb5824ae1143f10ed.png(Overview)中的Action标签里点击查看。

这个是Overview中的 Heap Dump Overview视图,从工具栏中点开,这是一个全局的内存占用信息

Used heap dump

79.7 MB

Number of objects

1,535,626

Number of classes

8,459

Number of class loaders

74

Number of GC roots

2,722

Format

hprof

JVM version

Time

格林尼治标准时间+0800上午9时20分37秒

Date

2014-7-2

Identifier size

32-bit

File path

E:\jmap\map.bin

File length

108,102,005

Total: 12 entries

然后可以点开SystemProperties和Thread Overview进行查看,我这里就不贴了内容比较多。

Dominator Tree

f567dfdf65eeb198a6540875aba11501.png

我们可以看到ibatis占了较多内存

Top consumers

5a251cfb871b7dadcf17da14c4bc3755.png

这张图展示的是占用内存比较多的对象的分布,下面是具体的一些类和占用。

500461e027087bb9a9eb6862d8dc3bf3.png

按等级分布的类使用情况,其实也就是按使用次数查看,java.lang.Class被排在第一

c2030fd8ebad241343e26ef938d1cac6.png

还有一张图是我们比较关心的,那就是按包名看占用,根据包我们知道哪些公共用的到jar或自己的包占用

12974b19e0185607e1f473128dc38bd2.png

这样就可以看到包和包中哪些类的占用比较高。

Leak Suspects

dc447e3ceeef50d4a2bb282af23d4e92.png

从这份报告,看到该图深色区域被怀疑有内存泄漏,可以发现整个heap只有79.7M内存,深色区域就占了62%。所以,MAT通过简单的报告就说明了项目是有可疑代码的,具体点开详情来找到类,

a50a8c201789e095c1a539bcf57a0322.png

6bfa1b3fe2234daac2980b3cf8bd0b53.png

165da6bd9651bbf895104ff6541eaa28.png

点击鼠标,在List Objects-> with outgoing references下可以查看该类都引用了什么对象,由此查看是否因为其他对象导致的内存问题。

下面继续查看pool的gc ROOT

如下图所示的上下文菜单中选择 Path To GC Roots -> exclude weak references, 过滤掉弱引用,因为在这里弱引用不是引起问题的关键。

进入查看即可,我这儿的代码没有问题,就不用贴了。

c704225dd3d998f4c362608f47d7b017.png

The classloader/component "org.apache.catalina.loader.WebappClassLoader @ 0xa34cde8" occupies 19,052,864 (22.80%) bytes. The memory is accumulated in one instance of "java.util.HashMap$Entry[]" loaded by "".

Keywords

java.util.HashMap$Entry[]

org.apache.catalina.loader.WebappClassLoader @ 0xa34cde8

这段话是在工具中提示的,他告诉我们WebappClassLoader占了19,052,864字节的容量,这是tomcat的类加载器,JDK自带的系统类加载器中占用比较多的是HashMap。这个其实比较正常,大家经常用map作为存储容器。

除了在上一页看到的描述外,还有Shortest Paths To the Accumulation Point和Accumulated Objects部分,这里说明了从GC root到聚集点的最短路径,以及完整的reference chain。观察Accumulated Objects部分,java.util.HashMap的retained heap(size)最大,所以明显类实例都聚集在HashMap中了。

e3479e16a5c3b4701d571b222bdc0d7f.png

来看看Accumulated Objects by Class区域,这里能找到被聚集的对象实例的类名。java.util.HashMap类上头条了,被实例化了5573次,从这儿看出这个程序不存在什么问题,因为这个数字是比较正常的,但是当出问题的时候我们都会看到比较大的自定义类会在前面,而且占用是相当高。

当然,mat这个工具还有很多的用法,这里把我了解的分享给大家,不管如何,最终我们需要得出系统的内存占用,然后对其进行代码或架构,服务器的优化措施!

参考文献:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值