当前位置: 首页 > 科技观察

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

时间:2023-03-18 22:19:58 科技观察

MAT不是***工具,它不处理所有类型的堆存储文件。但是主流厂商和格式,比如Sun、HP、SAP使用的HPROF二进制堆存储文件,IBM的PHD堆存储文件,都可以很好解析。让我们来看看如何去做,也许它会对你有用。官方文档:http://help.eclipse.org/luna/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.htmlOutOfMemoryError一般有两种原因:1.内存泄漏,对象有beenDead,不能被垃圾回收器自动回收,可以通过找出代码泄露的位置和原因来确定解决方案;2、内存溢出,内存中的对象肯定还存活,说明Java堆分配空间不足,查看堆设置大小(-Xmx和-Xms),查看代码是否存在对象生命周期为太久或保持太久的状态。1.使用jmap生成堆信息,这样在E盘的jmap文件夹下会有一个map.bin堆信息文件2.将堆信息导入mat进行分析3.生成分析报告mat可以生成多份报告供我们:让我们看看生成的数据如何帮助我们。从上图中,你可以看到它的大部分功能。在饼图上,您会发现转储的大小以及类、对象和类加载器的数量。在下方,饼图提供了令人印象深刻的对象转储。将鼠标移到切片上以在左侧的对象检查器中查看对象详细信息。在下面的Action标签中:Histogram可以列出内存中的对象,对象的数量和大小。DominatorTree可以列出那个线程,以及线程下面那些对象占用的空间。顶级消费者以图形方式列出最受欢迎的对象。LeakSuspects通过MA自动分析泄漏原因。HistogramClassName:类名,java类名Objects:类的对象个数,已经创建了多少个对象ShallowHeap:一个对象的内存消耗,不包括对其他对象的引用RetainedHeap:浅堆的总和,也就是对象GC后可以回收的内存总和。一般来说,ShallowHeap堆中的对象与预留内存大小相同。当对象达到堆内存量时,对象将被释放并被垃圾收集。一组主要对象的保留设置,例如特定类的所有对象,或由类加载器加载的特定类的所有对象或只是一组任意对象,是如果主要对象被释放的对象组所有对象的设置变得不可访问。保留设置包括这些对象和仅通过这些对象的所有其他对象。保留大小是总堆大小中包含的所有对象的保留。摘自eclipse的详细解释,建议你查看Shallowheap&Retainedheap,这是一个很重要的概念。这里我们使用工具提供的正则来搜索自己的类,排序后看哪些占用比较多。左边可以看到类的详细使用情况,比如所属的包,父类是谁,所属的类加载器,内存地址,占用大小和回收情况等。#p#这里有一个工具,可以根据自己的需要进行分组搜索。类分组类似于我们sql中的groupby~~这里可以看到上面3个选项,分别生成概览、泄漏嫌疑人、顶级组件数据,不过这里不是图表,如果想看图表在(Overview)单击“操作”选项卡中的“查看”。这是Overview中的HeapDumpOverview视图。从工具栏中单击它。这是全局内存使用信息。使用的堆转储79.7MB对象数量1,535,626类数量8,459类加载器数量74GC根数量2,722格式hprofJVM版本时间GMT+08009:20:37AM日期2014-7-2标识符大小32-bit文件路径E:\jmap\map.binFilelength108,102,005Total:12entry然后可以点S检查systemProperties和线程概述。我不会在这里发帖。DominatorTree有很多内容。我们可以看到ibatis占用的内存比较多。Topconsumers此图显示了占用内存较多的对象的分布。下面是一些具体的。班级和入住率。按级别分布的类的使用情况,其实是按照使用次数来看的。java.lang.Class排名靠前。还有一个我们比较关心的图,就是按包名看占用情况。根据包裹我们知道什么?常用的jar或者自己的包占用,可以看到包里面有哪些包,哪些类占用比较高。#p#LeakSuspects从这份报告中我们可以看出,图片的暗区疑似存在内存泄漏。可以发现整个堆内存只有79.7M,暗区占62%。因此,MAT通过一个简单的报告显示该项目存在可疑代码。点击详情找到类,点击鼠标,在ListObjects->withoutgoingreferences下可以查看该类引用了哪些对象。在这里查看是否是其他对象导致的内存问题。接下来继续查看pool的gcROOT。在下图所示的上下文菜单中选择PathToGCRoots->excludeweakreferences来过滤掉弱引用,因为弱引用不是这里问题的关键。只需输入并检查。我这里的代码没有问题,就不贴了。类加载器/组件“org.apache.catalina.loader.WebappClassLoader@0xa34cde8”占用19,052,864(22.80%)字节。内存累积在“”加载的“java.util.HashMap$Entry[]”实例中。关键字java.util.HashMap$Entry[]org.apache.catalina.loader.WebappClassLoader@0xa34cde8这个工具中提示段落。他告诉我们,WebappClassLoader占用了19,052,864字节的容量,这是tomcatJDK的类加载器,JDK自带的系统类加载器,占用了很多HashMap。这其实很正常。人们经常使用地图作为存储容器。除了上一页的描述外,还有ShortestPathsTotheAccumulationPoint和AccumulatedObjects部分,说明了从GCroot到堆积点的最短路径,以及完整的引用链。观察AccumulatedObjects部分,java.util.HashMap的retainedheap(size)***,可见类实例都聚集在了HashMap中。看一下AccumulatedObjectsbyClass区域,您可以在其中找到正在聚合的对象实例的类名。java.util.HashMap类成为头条新闻,它被实例化了5573次。从这里可以看出这个程序是没有问题的,因为这个数字是比较正常的,但是一旦出现问题,我们就会看到一个比较大的self。定义类会在最前面,占用率蛮高的。当然,垫子工具还有很多用法。下面我就把我知道的分享给大家。不管怎样,我们需要找出系统的内存使用情况,然后对其进行代码或架构和服务器优化措施!参考资料:http://www.eclipse.org/mat/about/screenshots.phphttp://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/本文来自:http:///my.oschina.net/biezhi/blog/286223