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

1、概论

  • 每每面试谈到有没有分析过内存泄漏、内存溢出等问题时我都在想,线上真的没给我机会啊,今天就自己创造机会来分析一下
    • 安装使用MAT(Eclipse Memory Analyzer)呗认为是傻瓜式分析工具
    • 获取堆转存文件(*.hprof)
    • 导入文件分析

2、安装MAT(Eclipse Memory Analyzer)

  • 安装方式有两种
  • 解压后可修改运行内存两种方式
    • 根目录下MemoryAnalyzer.ini文件,默认1024m可根据实际情况调整使用 Eclipse Memory Analyzer 进行堆转储文件分析
    • 修改启动参数,MemoryAnalyzer.exe -vmargs -Xmx1024m
  • 另外,如果你需要用 MAT 来分析 IBM JVM 生成的 dump 文件的话,还需要额外安装 IBM Diagnostic Tool Framework ,具体的下载和安装配置步骤请参见:http://www.ibm.com/developerworks/java/jdk/tools/dtfj.html

3、获取堆转存文件(*.hprof)

  • 有三种方式获取
    • 设置JVM参数:-XX:+HeapDumpOnOutOfMemoryError

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

    • 设置JVM参数:-XX:+HeapDumpOnCtrlBreak

      • 上种是发生泄漏时生成文件,这种不泄漏,小心大文件

    • 使用JMap命令
      • JMap -dump:format=b,file=<dumpfile> <pid>
      • 例如:JMap -dump:format=b,file=dump.hprof 进程号

4、导入文件分析

  • 首先,启动前面安装配置好的 Memory Analyzer tool , 然后选择菜单项 File- Open Heap Dump 来加载需要分析的堆转储文件。文件加载完成后,你可以看到如图 
  • 使用 Eclipse Memory Analyzer 进行堆转储文件分析
  • 我们着重看(报表)Reports,点击Leak Suspects(泄露疑点)如图内存消耗的整体状况
  • 如果出现内存泄漏深色的将占满,目前使用了7.9MB
  • 使用 Eclipse Memory Analyzer 进行堆转储文件分析
  • 问题:什么样的对象要被回收?
    • 想到的是“可达性分析算法”从GC ROOT起对象正在被引用说明对象存活,未被引用说明要被回收
  • 问题:哪些节点被定义为GC ROOT?
    • 栈内对象的引用
    • 静态变量引用的对象
    • 静态常量引用的对象
    • 内部方法引用
  • 了解了可达性分析算法的基础知识之后,点击Details
  • 使用 Eclipse Memory Analyzer 进行堆转储文件分析
  •  Accumulated Objects in Dominator Tree:着重看这个里边会有占用百分比及引用对象,很明显,里边的对象名一定让你大吃一惊

参考文献