Eclipse Memory Analyze 是Java 堆转储文件分析工具,可以帮助你发现内存漏洞和减少内存消耗。

概述

对于大型 JAVA 应用程序来说,再精细的测试也难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现。JVM 能够记录下问题发生时系统的部分运行状态,并将其存储在堆转储 (Heap Dump) 文件中,从而为我们分析和诊断问题提供了重要的依据。

通常内存泄露分析被认为是一件很有难度的工作,一般由团队中的资深人士进行。不过,今天我们要介绍的 MAT(Eclipse Memory Analyzer)被认为是一个“傻瓜式“的堆转储文件分析工具,你只需要轻轻点击一下鼠标就可以生成一个专业的分析报告。和其他内存泄露分析工具相比,MAT 的使用非常容易,基本可以实现一键到位,即使是新手也能够很快上手使用。

MAT 的使用是如此容易,你是不是也很有兴趣来亲自感受下呢,那么第一步我们先来安装 MAT。

安装

安装方式主要有2种:eclipse插件和软件版的。

1、eclipse插件安装很简单,点击help ---install new software------add 然后添加新地址,路径为:http://download.eclipse.org/mat/1.3/update-site/    然后

2、软件版的安装路径为:http://www.eclipse.org/mat/downloads.php ,下载windows即可。

配置环境参数

安装完成之后,为了更有效率的使用 MAT,我们还需要做一些配置工作。因为通常而言,分析一个堆转储文件需要消耗很多的堆空间,为了保证分析的效率和性能,在有条件的情况下,我们会建议分配给 MAT 尽可能多的内存资源。你可以采用如下两种方式来分配内存更多的内存资源给 MAT。

一种是修改启动参数 MemoryAnalyzer.exe -vmargs -Xmx4g

另一种是编辑文件 MemoryAnalyzer.ini,在里面添加类似信息 -vmargs – Xmx4g。

至此,MAT 就已经成功地安装配置好了,开始进入实战吧。

编写内存溢出程序如下:

程序1:

[java] view plaincopy
  1. public class HeapOOM {
  2. static class oomObject{}
  3. public static void main(String[] args){
  4. List<oomObject> list=new ArrayList<oomObject>();
  5. while(true)
  6. list.add(new oomObject());
  7. }
  8. }

程序2:

[java] view plaincopy
  1. 清单 1. 内存泄漏的代码段
  2. while (1<2)
  3. {
  4. Person person = new Person("name","address",i);
  5. v.add(person);
  6. person = null;
  7. }

获得堆转储文件

巧妇难为无米之炊,我们首先需要获得一个堆转储文件。为了方便,本文采用的是 Sun JDK 6。通常来说,只要你设置了如下所示的 JVM 参数:

-XX:+HeapDumpOnOutOfMemoryError

JVM 就会在发生内存泄露时抓拍下当时的内存状态,也就是我们想要的堆转储文件。

如果你不想等到发生崩溃性的错误时才获得堆转储文件,也可以通过设置如下 JVM 参数来按需获取堆转储文件。

-XX:+HeapDumpOnCtrlBreak

除此之外,还有很多的工具,例如 JMap,JConsole 都可以帮助我们得到一个堆转储文件。本文实例就是使用 JMap 直接获取了 Eclipse Galileo 进程的堆转储文件。您可以使用如下命令:

JMap -dump:format=b,file=<dumpfile> <pid>

不过,您需要了解到,不同厂家的 JVM 所生成的堆转储文件在数据存储格式以及数据存储内容上有很多区别, MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如 Sun, HP, SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的 PHD 堆存储文件等都能被很好的解析(您需要安装额外的插件,请参考 相关说明,本文不作详细解释)。

然后为你的eclipse或者TOMCAT加上生产 .hprof文件的配置,

然后就到了参数设置的页面,按照A,B的顺序设置参数:(-XX:+HeapDumpOnOutOfMemoryError)避免写错误可以copy

运行错误的程序代码会看见以下结果:

那么这时候就生成了一个文件java_pid3708.hprof,这个文件 在你的项目的根目录下

生成分析报告

首先,启动前面安装配置好的 Memory Analyzer tool , 然后选择菜单项 File- Open Heap Dump 来加载需要分析的堆转储文件。文件加载完成后,你可以看到如图 4 所示的界面:

图 4. 概览

通过上面的概览,我们对内存占用情况有了一个总体的了解。先检查一下 MAT 生成的一系列文件。

图 5. 文件列表

可以看到 MAT 工具提供了一个很贴心的功能,将报告的内容压缩打包到一个 zip 文件,并把它存放到原始堆转储文件的存放目录下,这样如果您需要和同事一起分析这个内存问题的话,只需要把这个小小的 zip 包发给他就可以了,不需要把整个堆文件发给他。并且整个报告是一个 HTML 格式的文件,用浏览器就可以轻松打开。

接下来我们就可以来看看生成的报告都包括什么内容,能不能帮我们找到问题所在吧。您可以点击工具栏上的 Leak Suspects 菜单项来生成内存泄露分析报告,也可以直接点击饼图下方的 Reports->Leak Suspects 链接来生成报告。

图 6. 工具栏菜单

回页首

分析三步曲

通常我们都会采用下面的“三步曲”来分析内存泄露问题:

首先,对问题发生时刻的系统内存状态获取一个整体印象。

第二步,找到最有可能导致内存泄露的元凶,通常也就是消耗内存最多的对象

接下来,进一步去查看这个内存消耗大户的具体情况,看看是否有什么异常的行为。

下面将用一个基本的例子来展示如何采用“三步曲”来查看生产的分析报告。

查看报告之一:内存消耗的整体状况

图 7. 内存泄露分析报告

如图 7 所示,在报告上最醒目的就是一张简洁明了的饼图,从图上我们可以清晰地看到一个可疑对象消耗了系统 99% 的内存。

在图的下方还有对这个可疑对象的进一步描述。我们可以看到内存是由 java.util.Vector 的实例消耗的,com.ibm.oti.vm.BootstrapClassLoader 负责这个对象的加载。这段描述非常短,但我相信您已经可以从中找到很多线索了,比如是哪个类占用了绝大多数的内存,它属于哪个组件等等。

接下来,我们应该进一步去分析问题,为什么一个 Vector 会占据了系统 99% 的内存,谁阻止了垃圾回收机制对它的回收。

查看报告之二:分析问题的所在

首先我们简单回顾下 JAVA 的内存回收机制,内存空间中垃圾回收的工作由垃圾回收器 (Garbage Collector,GC) 完成的,它的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。

在垃圾回收机制中有一组元素被称为根元素集合,它们是一组被虚拟机直接引用的对象,比如,正在运行的线程对象,系统调用栈里面的对象以及被 system class loader 所加载的那些对象。堆空间中的每个对象都是由一个根元素为起点被层层调用的。因此,一个对象还被某一个存活的根元素所引用,就会被认为是存活对象,不能被回收,进行内存释放。因此,我们可以通过分析一个对象到根元素的引用路径来分析为什么该对象不能被顺利回收。如果说一个对象已经不被任何程序逻辑所需要但是还存在被根元素引用的情况,我们可以说这里存在内存泄露。

现在,让我们开始真正的寻找内存泄露之旅,点击“Details ”链接,可以看到如图 8 所示对可疑对象 1 的详细分析报告。

图 8. 可疑对象 1 的详细分析报告

  1. 我们查看下从 GC 根元素到内存消耗聚集点的最短路径:
图 9. 从根元素到内存消耗聚集点的最短路径

我们可以很清楚的看到整个引用链,内存聚集点是一个拥有大量对象的集合,如果你对代码比较熟悉的话,相信这些信息应该能给你提供一些找到内存泄露的思路了。

接下来,我们再继续看看,这个对象集合里到底存放了什么,为什么会消耗掉如此多的内存。

图 10. 内存消耗聚集对象信息

在这张图上,我们可以清楚的看到,这个对象集合中保存了大量 Person 对象的引用,就是它导致的内存泄露。

参考网站:http://my.oschina.NET/biezhi/blog/286223

Eclipse Memory Analyzer 使用技巧相关推荐

  1. Eclipse Memory Analyzer(MAT) 使用总结

    前言 在日常的开发工作中,遇到生产环境报OOM的问题时,你首先会想到采用哪些方式并使用什么样的工具对OOM问题进行分析,定位和解决呢? 实际现场环境无非有这么两种,第一种,如果项目所在的生产服务器不允 ...

  2. 一次使用 Eclipse Memory Analyzer 分析 Tomcat 内存溢出

    最近,线上生产系统突然频繁的 JVM 内存报警!但本系统近期内并没有上线改动! 为了能查清内存报警的原因,使用 Eclipse Memory Analyzer tool(MAT)对 JVM Dump ...

  3. 内存映像分析工具Eclipse Memory Analyzer

    1. Eclipse Memory Analyzer安装 Help ->Eclipse Marketplace,搜索Memory,点击install,->confirm->同意证书内 ...

  4. 一次使用Eclipse Memory Analyzer分析weblogic内存溢出

    前言 在平时开发.测试过程中.甚至是生产环境中,有时会遇到OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题.我们需要找造成OutOfMemoryError原因.一般有两种情况 ...

  5. Eclipse Memory Analyzer 的使用

    原文出处:郭霖,http://blog.csdn.net/sinyu890807/article/details/42238633?locationNum=4 Eclipse Memory Analy ...

  6. 使用 Eclipse Memory Analyzer 进行堆转储文件分析

    概述 对于大型 JAVA 应用程序来说,再精细的测试也难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现.JVM 能够记录 ...

  7. Eclipse Memory Analyzer以及内存泄露的原因

    Eclipse Memory Analyzer是一个非常棒的堆内存分析工具,是JDK自带的堆分析工具jhat的一个非常好的替代品,能够快速地定位Java内存泄露的原因.       可能有的同学会问, ...

  8. solr analyzer_查看您的Solr缓存大小:Eclipse Memory Analyzer

    solr analyzer Solr使用不同的缓存来防止请求期间过多的IO访问和计算. 如果索引不是很频繁发生,则可以通过使用这些缓存来获得巨大的性能提升. 根据索引数据的结构和缓存的大小,它们可能会 ...

  9. 查看您的Solr缓存大小:Eclipse Memory Analyzer

    Solr使用不同的缓存来防止请求期间过多的IO访问和计算. 当索引不是很频繁发生时,您可以通过使用这些缓存来获得巨大的性能提升. 根据索引数据的结构和缓存的大小,它们可能会变得很大,并占用堆内存的很大 ...

最新文章

  1. Delphi解析类似\u97e9这样的Unicode字符串
  2. 【Verilog HDL 训练】第 04 天(竞争、冒险、译码等)
  3. java 面试题汇总
  4. 递推DP UVA 1366 Martian Mining
  5. C++中的引用(257BinaryTreePath)
  6. rails4 mysql2_ruby-on-rails – Rails 4 – Gem :: LoadError:为数据库适配器指定了“mysql2”,但gem未加载...
  7. [骨科手术导航]2D/3D医学图像配准研究_罗博博_南方科技大学
  8. 大数据培训:Zookeeper集群管理与选举
  9. linux jdk1.7 tomcat mysql_RedHat Linux 下安装JDK 1.7+MySQL 5.0+Tomcat 7.0.27过程
  10. ip校验和及udp校验和的计算方法
  11. 在text html模版中写js,Rails3使用text/html内容类型而不是text/javascript呈现js.erb模板...
  12. mysql常用字符串操作函数大全,以及实例
  13. oracle中decode的用法(例子)
  14. 项目管理软件 OpenProj
  15. Symbian 调用Wap浏览器
  16. import语句在包名前加static
  17. RocketMQ中文文档(译)
  18. 快递100接口使用整理
  19. 2016年全国高中数学联合竞赛试题及详细解答
  20. SAP中汇率取值选择逻辑分析测试

热门文章

  1. Linux上创建和更改硬链接和符号链接(软连接)
  2. (三)5.自动控制原理 Time domain analysis and correct 稳态误差
  3. K8S 完全安装手册
  4. 作业4 | Lloyd-Max标量量化器DCMP基本原理
  5. python 字符串方法 replace_python字符串方法replace()简介
  6. 《HelloGitHub》第 65 期
  7. matplotlib:使用子图实现简易象形图
  8. 从零开始学R(四)——常用命令:帮助,文件导入与导出与基本操作
  9. 2020年史上最全移动端Web整理从开发基础到实战(三)
  10. 一个高效的敏感词过滤方法(PHP)