开发、应用中老是会遇到OutOfMemory异常,而且常常是过一段时间内存才被吃光,这里可以利用java heap dump出jvm内存镜像,然后再对其进行分析来查找问题。

平常利用jmap -dump:format=b,file=/path/file.hprof <pid> 这个java自带的工具来dump heap很方便,但当内存溢出问题发生的比较快的情况下,该命令就有可能来不及或无效。

这个时候在应用启动时配置相关的参数 -XX:+HeapDumpOnOutOfMemoryError就比较方便,当然可以再加上-XX:HeapDumpPath=/path/file.hprof 来指定文件的输出路径。
不知道怎么用这些参数?就在你启动应用的时候加,如:
/usr/lib/jvm/java-1.6.0/bin/java -server -Xms1536m -Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=64m -XX:MaxPermSize=64m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/file.hprof -Djava.ext.dirs=/xxx/lib/ ClassName

可以利用java自带的 $JAVA_HOME/bin/jhat -J-Xmx512m /path/file.hprof分析生成的堆转储文件,尽管不太友好。

比较好的一种方式是使用Memory Analyzer 进行堆转储文件分析

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

配置环境参数

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

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

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

生成分析报告

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

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

文件列表

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

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

分析三步曲

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

至此,我们已经拥有了足够的信息去寻找泄露点,回到代码,我们发现,是下面的代码导致了内存泄露 :

内存泄漏的代码段

public class HeapOOM {
public static void main(String[] args) {
List<Person> list = new ArrayList<Person>();
while(true){
Person person = new Person(25, "zhangsan");
list.add(person);
}
}
}

MAT(Memory Analyzer Tool)内存分析工具的使用的更多相关文章

  1. 内存分析工具-MAT(Memory Analyzer Tool)

    内存分析工具-MAT(Memory Analyzer Tool) 首先查看如下代码,main函数中有一个成员变量map,map里被循环放入对象Hanson,hanson持有姓名和age还有friend ...

  2. 使用MAT(Memory Analyzer Tool)工具分析dump文件--转

    原文地址:http://gao-xianglong.iteye.com/blog/2173140?utm_source=tuicool&utm_medium=referral 前言 生产环境中 ...

  3. MAT(Memory Analyzer Tool)工具入门介绍

    1.MAT是什么? MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速.功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗 ...

  4. MAT(Memory Analyzer Tool)工具入门介绍(转)

    1.MAT是什么? MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速.功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗 ...

  5. 【转】MAT(Memory Analyzer Tool)工具入门介绍

    1.MAT是什么? MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速.功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗 ...

  6. MAT Memory Analyzer Tool 插件安装(图解)

    MAT Memory Analyzer Tool 插件安装(图解) 原文地址 @author YHC 前段时间做了一个项目,Exception in thread "main" j ...

  7. Android 内存分析工具 MAT(Memory Analyzer Tool)

    如果使用DDMS确实发现了我们的程序中存在内存泄漏,那又如何定位到具体出现问题的代码片段,最终找到问题所在呢?如果从头到尾的分析代码逻辑,那肯定 会把人逼疯,特别是在维护别人写的代码的时候.这里介绍一 ...

  8. 转载:MAT Memory Analyzer Tool使用示例

    地址:http://blog.csdn.net/yanghongchang_/article/details/7711911 以下是一个会导致java.lang.OutOfMemoryError: J ...

  9. [性能测试]:内存泄漏以及MAT(Memory Analyzer Tool)工具使用分析

    一.今天在查看服务器时候,发现内存使用率直接就到99%了, 二.用ps -uaxw查看一下,每个占用内存较多的进程情况: 三,挑出可疑的进程,生成dump文件: jmap -dump:format=b ...

随机推荐

  1. windows下mysql配置

    windows下mysql配置   忙活了大半天,总算配置好了,本文献给windows下没试用过Mysql的小白,勿喷 http://blog.csdn.net/z1074907546/article ...

  2. Ubuntu16.04 14.04 配置caffe(CPU only)

    1.安装依赖 sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-seria ...

  3. tqdm:Python 进度条

    Tqdm 是 Python 进度条库,可以在 Python 长循环中添加一个进度提示信息.用户只需要封装任意的迭代器,是一个快速.扩展性强的进度条工具库. 用法:tqdm(iterator) 代码地址 ...

  4. cv2 与 matplotlib 的 Bug 记录

    cv2 的 imread 无法读取中文路径 解决方案: img = cv2.imdecode(np.fromfile(image_path,dtype=np.uint8),cv2.IMREAD_COL ...

  5. Jmeter脚本录制方法(一)分别使用Badboy录制和Jmeter自带的代理服务器录制

    Jmeter录制方式分三种,分别是:使用Badboy录制.Jmeter自带的代理服务器录制和手工录制,今天先介绍前两种录制方法. Badboy录制 Badboy是用C++开发的动态应用测试工具, 其拥 ...

  6. 概率dp总结

    终于做到概率dp题了,开个总结帖记录一下 首先是几篇论文:有关概率和期望问题的研究 做了这么多题,实际上没什么特别好总结的,就是搞清状态和转移,顺着写就行了,和基本dp差不多 概率是由过去到现在dp[ ...

  7. 吴恩达-coursera-机器学习-week4

    第八.神经网络:表述(Neural Networks: Representation) 8.1 非线性假设 8.2 神经元和大脑 8.3 模型表示1 8.4 模型表示2 8.5 样本和直观理解1 8. ...

  8. ROS知识(21)----ROS C++代码格式化

    这里提供两种方法. 第一种方法:clang_format 1.安装clang format sudo apt-get install -y clang-format-3.6 2.从github的ros ...

  9. OS X - 在80端口启动Nginx

    不知道你是怎么在你的mac上安装nginx的,但是如果你跟我一样: brew install nginx 然后你会发现你的nginx.conf中的端口是8080. 于是你可能像我一样试着把端口改为80 ...

  10. dp和px,那些不得不吐槽的故事——Android平台图片文字元素单位浅析 (转)

    一个优秀的手机软件,不仅要有精巧的功能,流畅的速度,让人赏心悦目的UI也往往是用户选择的重要理由.作为移动产品的PM,也需要了解一些在UI设计中的基本知识. 1. px和pt,一对好伙伴 在视觉设计中 ...