Use the mat tool to analyze memory usage

MAT is not a panacea, it cannot handle all types of heap storage files. But more mainstream manufacturers and formats, such as the HPROF binary heap storage file used by Sun, HP, SAP, and IBM's PHD heap storage file, can be well parsed. Let's take a look at how to do it, maybe it will work for you. Official documentation: http://help.eclipse.org/luna/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html

There are generally two reasons for OutOfMemoryError:

1. Memory leaks, the object is dead and cannot be automatically recycled by the garbage collector. Only by finding out the location and cause of the leaked code can the solution be determined;

2. Memory overflow, the objects in the memory must still survive, which means that the Java heap allocation space is insufficient, check the heap setting size (-Xmx and -Xms), and check whether the code has an object whose life cycle is too long and the holding time is too long. long case.

1. Generate heap information with jmap
 

In this way, there will be a heap information file of map.bin in the jmap folder of the E disk.

2. Import heap information into mat for analysis   

3. Generate analysis report

mat can generate multiple reports for us:

Let's take a look at how the generated data can help us

Most of its functionality can be seen from the above image, on the pie chart, you will find the size and number of dumped classes, objects and class loaders.

Right below, the pie chart gives an impression of the largest object dump. Move your mouse over a piece to see the object in the object's detail inspection on the left. In the Action tag below:

  • Histogram can list objects in memory, the number and size of objects.

  • The Dominator Tree can list that thread, and the space occupied by those objects below the thread.

  • Top consumers list the largest objects graphically.

  • Leak Suspects automatically analyzes the cause of leaks through MA.

Histogram

  • Class Name : class name, java class name

  • Objects : The number of objects of the class, how many were created

  • Shallow Heap: The consumption size of an object's memory, excluding references to other objects

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


一般来说,Shallow Heap堆中的对象是它的大小和保留内存大小相同的对象是堆内存的数量时,将释放对象被垃圾收集。
保留设置一组主要的对象,例如一个特定类的所有对象,或所有对象的一个特定的类装入器装入的类或者只是一群任意对象,是释放的组对象如果所有对象的主要设置变得难以接近的。保留设置包括这些对象以及所有其他对象只能通过这些对象。保留大小是总堆大小中包含的所有对象的保留。摘自eclipse


关于的详细讲解,建议大家查看Shallow heap & Retained heap,这是个很重要的概念。

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

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

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

这里可以看到上面3个选项,分别生成overview、leak suspects、top components数据,但是这儿生成的不是图表,如果要看图表在(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

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

Top consumers

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

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

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

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

Leak Suspects

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

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

下面继续查看pool的gc ROOT

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

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


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 "<system class loader>".

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中了。

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

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

参考文献:

http://www.eclipse.org/mat/about/screenshots.php

http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/

本文出自:http://my.oschina.net/biezhi/blog/286223

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326268037&siteId=291194637