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

时间:2023-01-13 10:12:37

国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html
内部邀请码:C8E245J (不写邀请码,没有现金送)
国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为中国PE第一股,市值超1000亿元。 

------------------------------------------------------------------------------------------------------------------------------------------------------------------

在工作中可能会遇到内存溢出这种灾难性的问题,那么程序肯定是存在问题,找出问题至关重要,上一篇文章讲了jmap命令的使用方法,当然用jmap导出的文件我们也看不懂啊,那就交给memory analyzer(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生成堆信息

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

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

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

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

3. 生成分析报告

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

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

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

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

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

从上图可以看到它的大部分功能,在饼图上,你会发现转储的大小和数量的类,对象和类加载器。
正确的下面,饼图给出了一个印象最大的对象转储。移动你的鼠标一片看到对象中的对象的细节检查在左边。下面的Action标签中:

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

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

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

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

    Histogram

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

    • Class Name : 类名称,java类名

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

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

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


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


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

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

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

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

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

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

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

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

    这里可以看到上面3个选项,分别生成overview、leak suspects、top components数据,但是这儿生成的不是图表,如果要看图表在Java程序内存分析:使用mat工具分析内存占用(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

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

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

    Top consumers

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

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

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

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

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

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

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

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

    Leak Suspects

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

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

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

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

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

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

    下面继续查看pool的gc ROOT

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

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

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


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

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

    来看看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/

    Java程序内存分析:使用mat工具分析内存占用的更多相关文章

    1. Eclipse安装Mat工具分析教程

      一.关于Mat MAT是Memory Analyzer的简称,它是一款功能强大的Java堆内存分析器.可以用于查找内存泄露以及查看内存消耗情况.MAT是基于Eclipse开发的,是一款免费的性能分析工 ...

    2. JAVA程序测试时用到的与内存测试有关的东西

      1.JVM启动参数 垃圾回收器调用情况参数,使用如下参数可以看到程序何时启动GC进行垃圾回收,和垃圾回收的详细信息. java Test -XX:+PrintGCDetails -XX:+PrintG ...

    3. 12个提高Java程序员工作效率的工具

      Java开发者常常都会想办法如何更快地编写Java代码,让开发过程变得更加轻松,更加高效.目前,市面上涌现出越来越多的高效编程工具.团长总结了几个常用的工具,其中包含了大多数开发人员已经使用.正在使用 ...

    4. java程序员--小心你代码中的内存泄漏

      当你从c&c++转到一门具有垃圾回收功能的语言时,程序员的工作就会变得更加容易,因为你用完对象,他们会被自动回收,但是,java程序员真的不需要考虑内存泄露吗? 其实不然 1.举个例子-看你能 ...

    5. 内存泄漏 之 MAT工具的使用

      1 内存泄漏的排查方法 Dalvik Debug Monitor Server (DDMS) 是 ADT插件的一部分,其中有两项功能可用于内存检查 : ·    heap 查看堆的分配情况 ·     ...

    6. 【转】15款Java程序员必备的开发工具

      如果你是一名Web开发人员,那么用膝盖想也知道你的职业生涯大部分将使用Java而度过.这是一款商业级的编程语言,我们没有办法不接触它. 对于Java,有两种截然不同的观点:一种认为Java是最简单功能 ...

    7. 15款Java程序员必备的开发工具(转)

      如果你是一名Web开发人员,那么用膝盖想也知道你的职业生涯大部分将使用Java而度过.这是一款商业级的编程语言,我们没有办法不接触它 对于Java,有两种截然不同的观点: 一种认为Java是最简单功能 ...

    8. 15款Java程序员必备的开发工具

      如果你是一名Web开发人员,那么用膝盖想也知道你的职业生涯大部分将使用Java而度过.这是一款商业级的编程语言,我们没有办法不接触它. 对于Java,有两种截然不同的观点:一种认为Java是最简单功能 ...

    9. 编写Java程序,创建一个数学工具类,将该类设计为final类,Final 修饰符的使用。

      返回本章节 返回作业目录 需求说明: 创建一个数学工具类. 将该类设计为final类. 将该类的构造方法的访问权限定义为私有,以防止外界实例化该类. 在该类定义静态double类型常量π,其值为3.1 ...

    随机推荐

    1. setprecision、fixed、showpoint的用法总结

      首先要加头文件:iomanip 一:setprecision 作用:控制输出流显示浮点数的数字个数,setprecision(n)就是输出的n个数,会有四舍五入. 比如:double s=20.784 ...

    2. STM32下载调试驱动问题

      No Cortex-m SW device found解决办法 16.07.14 今天工作,遇到一个问题:用jlink采用SW下载模式时,一直显示No Cortex-m SW device found ...

    3. 【codevs2216】行星序列 线段树 区间两异同修改&plus;区间求和&ast;&ast;&ast;&ast;&ast;

      [codevs2216]行星序列 2014年2月22日3501 题目描述 Description “神州“载人飞船的发射成功让小可可非常激动,他立志长大后要成为一名宇航员假期一始,他就报名参加了“小小 ...

    4. IOS 在http请求中使用cookie

      原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://rainbird.blog.51cto.com/211214/805173 一直以 ...

    5. Spring国际化

      国际化(Internationalization)有时候被简称为i18n,因为有18个字母在国际化的英文单词的字母i和n之间.Spring对国际化的支持示例如下所示. 需要将spring.tld放到工 ...

    6. LOJ2540 &lbrack;PKUWC2018&rsqb; 随机算法 【状压DP】

      题目分析: 听说这题考场上能被$ O(4^n) $的暴力水过,难不成出题人是毕姥爷? 首先思考一个显而易见的$ O(n^2*2^n) $的暴力DP.一般的DP都是考虑最近的加入了哪个点,然后删除后递归 ...

    7. ArcEngine二次开发&comma;TOCControl控件上使用contextMenuStrip

      右键菜单,在二次开发中很实用,以前没用过,最近通过一本书了解到,一直想找这么一个控件来用. 一般的控件,将contextMenuStrip控件拖到所依托的控件上,然后输入自己想要的几个功能.  在所依 ...

    8. python获取当前日期

      今天群里一个人问了怎么获取当前时间的问题,以前接触过计算日期之差的,具体代码如下: import datetime d1=datetime.datetime(2014,3,14) d2=datetim ...

    9. java 使用内部类的理由

      每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响 内部类有效的实现了多重继承,也就是说,内部类允许继承多个非接口类型(类或抽象类) 如 ...

    10. &lbrack;Node&period;js&rsqb; 4&period; Modules

      4.2 Missing Exports Notice the two different files: high_five.js on the left side andapp.js on the r ...