前言

内存泄露和内存溢出的区别:内存泄露从老年代的增长情况看是缓慢上升的, 最终达到老年代上限才会导致溢出,有些内存泄露可能需要很长的时间发生, 所以说内存泄露更隐蔽, 不像内存溢出那样容易暴露(内存溢出直接抛出OOM), 而且内存长时间得不到释放会导致服务性能越来越差、gc时间变长、响应变慢:

1. 安装

在Eclipse help -> Eclipse Marketplace下搜索Memory:

按照操作流程安装完成,重启Eclipse.

2.获取Heapdump 文件

方法1

**/jdk/1.7.0_95l64/bin/jmap -dump:format=b,file=heapdump_name.hprof <pid>

方法2.

如果你的是spring boot项目且暴露了actuator里面的heapdump的api. 直接用下面的命令。

*/actuator/heapdump

可以每隔一段时间获取一个heapdump文件

3. Histogram 查询

利用Elipse 里Memory Analysis view打开你想分析的heapdump文件

打开Histogram

它按类名将所有的实例对象列出来,可以点击表头进行排序,在表的第一行可以输入正则表达式来匹配结果 :

4. 使用 Compare Basket 功能分析

利用Elipse 里Memory Analysis view依次打开多个heapdump文件

1. 菜单栏 window → compare basket ,打开比较窗口(如果最下面一栏已经有compare basket则这步不需要),如下图:

2. 依次打开3个dump的dashboard面板, 在下方的 Actions一栏点击"histogram"或"dominator tree"生成对应的直方图或支配树列表,如下图:

直方图或支配树都可以列出堆中存活的所有对象,但二者的维度不同, 直方图按照类型统计, 支配树是以对象维度统计。

如果你对项目代码比较熟悉, 通过直方图定位内存泄露会更快,因为它是按照类型全部平铺开的,如果这个项目不是你负责的, 建议使用支配树的方式, 因为支配树包含了对象之间的引用关系(支配树视图可以展开查看内部引用层级)

3. 我们以支配树做比对, 在最下面一栏的"Navigation History (window → navigation history)"里(直方图类似)找到在第2步打开的支配树dominator tree图标, 右键添加到compare basket, 如下图:

添加好后,打开 Compare Basket面板,得到结果:

4. 重复上面的2, 3步骤依次把其他的dump文件添加到"compare basket"栏, 然后点击右上角的红色感叹号, 生成比较结果,如下图:

(注意比较的dump文件的顺序,时间最早的在上面,可以通过右上角的上箭头↑和下箭头↓调整顺序)

生成的比对结果如下:

Shallow Heap一列后面的序号 #0, #1, #2 分别对应:

第一个dump文件占用的shallow size, 第二个dump文件占用的shallow size , 第三个dump文件占用的shallow size

Retained Heap #0, Retained Heap #1, Retained Heap #2 这3列分别对应:

第一个dump文件占用的retained size, 第二个dump文件占用的retained size , 第三个dump文件占用的retained size

红框 圈出的是内存连续增长的对象, 可以通过右边红框的retained heap看出内存变大的趋势

绿框 圈出的是没有变化的对象(至少在这3次比较中没有变化),

蓝框 圈出的是内存占用下降的对象

一般我们主要关注红框标出的对象, 因为这部分发生内存泄露的嫌疑最大

这里先区分两个概念:

Shallow Size

对象自身占用的内存大小,不包括它引用的对象。
针对非数组类型的对象,它的大小就是对象与它所有的成员变量大小的总和。
针对数组类型的对象,它的大小是数组元素对象的大小总和。

Retained Size

Retained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和。(间接引用的含义:A->B->C, C就是间接引用)
Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。
因为这里我们比较的是支配树, 所以按照retained heap倒序排列, 从左到右依次为: retained heap #0 → retained heap #1 → retained heap #2(以最后一个retained heap #2 倒序, 因为这个是最后一次dump的内存快照, 这样可以看出内存泄露的增长趋势)

5. 使用 Path To Gc Root 定位业务代码

还有另外一个内存泄露的嫌疑是"com.*.common.utils.ITextRendererPoolManager", 如上面比对结果的图:

单独在dominator tree支配树视图展开如图所示:

 ITextRendererPoolManager内部使用了apache的一个对象缓冲池, 目的可能是为了对象复用, 继续展开,如下图:

发现是pdf的一个工具类:org.xhtmlrenderer.pdf.ITextRenderer, 这个开源的pdf工具是我们项目的邮件功能在发送附件的时候生成pdf文档时引入的一个第三方jar包,开始怀疑是否是这个开源的pdf工具导致的内存泄露, 但是不清楚这个jar包是在哪里调用的?

这里可以通过"path to gc root"查看是谁在引用他, 即我们业务代码调用的地方,如下图:

这里先说下"path to gc root"选项的含义:

with all references : 所有引用, 包括强引用, 弱引用, 软引用, 虚引用
exclude weak reference : 排除弱引用
exclude soft reference : 排除软引用
。。。。
我们知道软引用, 弱引用这些在发生full gc时可能会被回收掉(回收时机不同, 具体可自行百度), 目的是不造成内存溢出。 一般引起内存溢出的都是强引用,所以你可以选择"exclude all ptantom/weak/soft reference"只查看强引用。

Eclipse Memory Analyzer分析内存使用总结相关推荐

  1. Memory Analyzer分析内存泄漏

    Memory Analyzer分析内存泄漏 模拟一次内存溢出 程序不断地向ArrayList添加对象,直至溢出 public class User {String userName;String pa ...

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

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

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

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

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

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

  5. Eclipse Memory Analyzer,内存泄漏插件,安装使用

    网上文档很多,但最初都有问题.整理一份,作为备份.使用过程:开发代码写完后,对可能出现内存溢出的代码,添加配置文件,生成.hprof文件,用memory Analyzer分析排查问题,且泄漏内存大小可 ...

  6. 使用Eclipse Memory Analyzer分析Tomcat内存溢出

    本文语言逻辑转载:http://tivan.iteye.com/blog/1487855 实际分析来源于自己的实际项目. 在平时开发.测试过程中.甚至是生产环境中,有时会遇到OutOfMemoryEr ...

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

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

  8. 使用Eclipse Memory Analyzer对Tomcat进行内存分析

    测试环境 Java : JDK1.6 Tomcat: Tomcat 5.5 Eclipse Memory Analyzer:EMA 1.2.1(直接去Eclipse下载,无需安装哈) 获得Heap D ...

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

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

最新文章

  1. 【C语言刷题】交换两个变量(包含不创建临时变量)的解法
  2. 记一次内存溢出的分析经历
  3. AI芯片初创公司单纯卖芯片还是捆绑算法的商业模式更好?
  4. IPSec的安全性如何?—微云MPLS
  5. Apache Shiro去掉URL中的JSESSIONID
  6. java异步执行任务
  7. RT-Thread pin设备驱动代码结构剖析
  8. 为什么你总办不到大额信用卡?
  9. 未发现数据源名称并且未指定默认驱动程序_看我如何发现NVIDIA GeForce Experience代码执行漏洞...
  10. win10多合一原版系统_手把手教你制作官方原版的WIN10系统安装盘
  11. 蚂蚁金服自研数据库打败Oracle拿下世界第一;三星手机全面退出中国;微软发布Windows 10X双屏系统 | 极客头条...
  12. 网易编程题-操作序列
  13. 父子组件如何实现通信
  14. 荣耀路由器w831刷linux,华为荣耀路由器登录入口:荣耀路由器WS831设置指南【图解】...
  15. 苹果应用商店审核_苹果应用商店AppStore审核规则指南
  16. 改编码格式_CAD多行文字编码讲解
  17. win10笔记本使用virtualbox鼠标失灵
  18. 正面管教php_我就这样走进正面管教
  19. Flutter 新版Navigator (一)
  20. 利用selenium携带cookies实现免登录

热门文章

  1. [转]iOS开发使用半透明模糊效果方法整理
  2. 坑爹BUG,没有详细的看还真看不出问题
  3. install cuda5 on ubuntu12.04
  4. javascript访问frame,iframe框架和href的定向
  5. Web前端 HTML 优化启动性能
  6. NGINX配置邮件代理服务器
  7. 容器编排技术 -- Kubernetes kubectl create clusterrole 命令详解
  8. 容器编排技术 -- 从零开始k8s
  9. Windows下自动备份Oracle数据库
  10. Spring事务管理示例JDBC