在最近的工作中,通过JProfiler解决了一个内存泄漏的问题,现将检测的步骤和一些分析记录下来,已备今后遇到相似问题时可以作为参考。

运行环境:

Tomcat6,jdk6,JProfiler8

内存泄漏的现象:

1. 在服务器中执行某些批量操作的时候,发现内存只升不降;就算gc后,内存也不能被完全释放;
2. 除非重启tomcat服务器,内存永远不会被释放,反复执行这些操作,会导致无可用内存,tomcat死掉;

使用JProfiler检查内存泄漏的步骤:

1. 初始化检验环境:

切换到“Live Memory-->All Objects”标签,可以看到当前tomcat中的对象情况。

在执行操作前,需要先运行“Run GC”,使jvm进行内存回收,清理无效的对象;

为了便于比较内存的增长情况,可以点击"Mark Current"按钮,来将当前内存使用情况作为参照;

点击后会显示“Difference”列,该列会列出对象数量的变化和变化比率;

2.打开内存记录:

点击“Start Recordings”按钮,开始记录。执行这步的主要目的是为下面“Heap Walker”,设置一个监控区间;如果不记录的话,“Heap Walker”将分析jvm虚拟机的所有内存,即耗时又不能准确的发现内存泄漏的原因。

3. 执行操作,执行gc;

执行会引起内存泄漏的操作,执行完进行内存回收;

可以点击下面的“update”按钮,进行视图的更新;

执行内存回收后,仍然存在于内存中的对象有可能是泄漏的对象;如下图,instance count中红色的部门为不能回收的对象,difference列列出了增加的对象数量和增幅;以String为例,在该操作中增加了31751个对象,增幅达到了14%,随后会在HeapWalker中观察这些对象,分析哪些对象是泄漏的;

一般引起泄漏的对象包括:String,char[],HashMap等,这些对象需要重点关注下;

4. 关闭内存记录:

点击“Stop Recordings”关闭内存记录,告诉jProfiler把这段记录作为分析对象;

5. 找到增加迅速的对象类型,打开HeapWalker:

在视图中找到增长快速的对象类型,一般包括String、char[]、Map等;

在这个操作中,String的增长速度很快。在Liver memory视图中找到String,点右键,选择“Show Selectiion In Heap Walker”,切换到HeapWarker 视图;

切换前会弹出选项页面,注意一定要选择“Select recorded  objects”;这样Heap Walker会在刚刚的那段记录中进行分析;否则,如果不勾选的话,他会分析tomcat的所有内存对象,这样既耗时又不准确;

6. 在HeapWalker中,找到泄漏的对象;

HeapWarker 会分析内存中的所有对象,包括对象的引用、创建、大小和数量;

通过切换到References页签,可以看到具体的对象;

在这些内存对象中,找到泄漏的对象(应该被回收);可以在该对象上点击右键,选择“Use Selected Instances”缩小对象范围;

7. 通过引用分析该对象:

在References引用页签中,可以看到该对象的的引用关系,可以切换incoming/outcoming,显示引用的类型:

incoming  表示显示这个对象被谁引用;

outcoming 表示显示这个对象引用的其他对象;

选择“Show In Graph”将引用关系使用图形方式展现;

选中该对象,点击“Show Paths To GC Root”,会找到引用的根节点;

在上图中,我们可以发现,这个String对象最终的引用是在Thread线程中的ThreadLocalMap对象中;这给我们提供了线索,我们需要在程序中查找有关ThreadLocalMap部分的代码,检查为什么这个对象没有被释放;这往往就是泄漏的根源。

8. 通过创建分析该对象:

如果第7步还不能定位内存泄露的地方,我们可以尝试使用Allocations页签,该页签显示对象是如何创建出来的;
我们可以从创建方法开始检查,检查所有用到该对象的地方,直到找到泄漏位置;

内存泄漏的原因分析:

通过上面的分析,这次内存泄露主要由下面的原因造成:
有操作将对象存放在ThreadLocal的静态变量中,引用不会被释放,所以该对象不会被回收,一直存在于内存中,导致内存泄漏;

参考资料:

1. 转载自: https://blog.csdn.net/coslay/article/details/43270311

2.《利用Java剖析工具JProfiler查找内存泄漏的方法》http://jingyan.baidu.com/article/9c69d48f552d5f13c9024e3b.html

jprofiler 查看程序内存泄露的更多相关文章

  1. Net Memory Profiler 分析.Net程序内存泄露

    Net Memory Profiler 分析.Net程序内存泄露 Haozes's Tech Space 人類的全部才能無非是時間和耐心的混合物 使用.Net Memory Profiler 分析.N ...

  2. Unix下C程序内存泄露检测工具:valgrind的安装使用

    Valgrind是一款用于内存调试.内存泄漏检测以及性能分析的软件开发工具. Valgrind的最初作者是Julian Seward,他于2006年由于在开发Valgrind上的工作获得了第二届Goo ...

  3. c++程序内存泄露检測工具

    功能: 用于检測c++程序的内存泄露. 原理: 事实上非常easy,就是通过函数的重载机制,捕获应用程序的new, new[] , delete , delete[], malloc,calloc,f ...

  4. valgrind--CPP程序内存泄露检查工具

    内存泄漏是c++程序常见的问题了,特别是服务类程序,当系统模块过多或者逻辑复杂后,很难通过代码看出内存泄漏. valgrind是一个开源的,检测c++程序内存泄漏有效工具,编译时加上-g选项可以定位到 ...

  5. Linux下C程序内存泄露检测

    在linux下些C语言程序,最大的问题就是没有一个好的编程IDE,当然想kdevelop等工具都相当的强大,但我还是习惯使用kdevelop工具,由于没有一个习惯的编程IDE,内存检测也就成了在lin ...

  6. 一次Java内存泄露处理手记

    现象 最近项目组从NET平台迁移到Java的Dubbo平台上,由于大家都是Java的生手,发生了蛮多的问题,以后一一记录.现在解决一个遇到的关于Java程序内存泄露的问题. 特别说明 Java萌新,理 ...

  7. 记一次调试python内存泄露的问题

    转载:http://www.jianshu.com/p/2d06a1a01cc3 这两天由于公司需要, 自己编写了一个用于接收dicom文件(医学图像文件)的server. 经过各种coding-de ...

  8. 实战Go内存泄露【转】

    最近解决了我们项目中的一个内存泄露问题,事实再次证明pprof是一个好工具,但掌握好工具的正确用法,才能发挥好工具的威力,不然就算你手里有屠龙刀,也成不了天下第一,本文就是带你用pprof定位内存泄露 ...

  9. Linux内存使用情况以及内存泄露情况

    1. 内存使用情况分析 http://www.360doc.com/content/15/1118/13/17283_514054063.shtml https://www.linuxidc.com/ ...

随机推荐

  1. MIME类型说明(HTTP协议中数据类型)

    MIME(HTTP协议中数据类型) MIME:多功能Internet邮件扩充服务.MIME类型的格式是"大类型/小类型",并与某一种文件的扩展名相对应. 常见的MIME类型: RT ...

  2. 【ASP.NET Core】使用最熟悉的Session验证方案

    如果大伙伴们以前写过 ASP 或 PHP 之类的,相信各位对基于 Session 的身份验证很熟悉(其实在浏览器端是结合 Cookie 来处理的).这种验证方式是比较早期的,操作起来也不复杂. a.用 ...

  3. Mongodb全备+增备+oplog恢复误删数据

    此时测试表中有7条数据,做个全备. 全备: mongodump --host=192.168.43.43 --port=37017 --oplog --out=/opt/mongo/fullbacku ...

  4. Unity——日志打印工具

    一.日志工具功能 封装Debug类,需要实现功能: 1.控制所有日志是否打印: 2.除了Log,Warning,Error外,给更多日志种类(不同颜色): 3.格式化打印日志: 4.不定参数,自动拼接 ...

  5. 计算机网络-5-9-TCP拥塞控制

    TCP拥塞控制 拥塞控制的一般原理 在计算机网络中的链路容量(带宽),交换节点中的缓存和处理机等,都是网络的资源,在某段时间,若对网络中某一资源的需求超过该资源所能提供的可用部分,网络性能就会变坏,这 ...

  6. js中数组的添加和移除

    1.引入js文件 <script src="../plugins/jQuery/jquery-2.2.3.min.js"></script>2.HTML中代 ...

  7. lua语言:时间

    转载请注明来源:https://www.cnblogs.com/hookjc/ 时间库函数 1.用数值表示时间值 用数字值来表示时间值,实际上时间值的本质就是一个数字值.例如:d = 11312864 ...

  8. 在Excel VBA中使用SQL到底优势在哪儿

    小爬在之前的博文中多次提到,可以在VBA中写SQL来操作Excel文件,实现各类数据处理和分析需求.那么,你可能有这样的疑问:Excel原生的VBA,数据透视表,数据分析功能不够吗,为啥一定要用SQL ...

  9. AppiumForWin安装

    尝试安装Windows版本的Appium 参考:http://www.cnblogs.com/fnng/p/4540731.html 第一步:安装node https://nodejs.org/en/ ...

  10. 赠送4本《 PHP 程序员面试笔试宝典》

    < PHP 程序员面试笔试宝典>历时一年,由机械工业出版社出版,在 2018 年 11 月问世.全书共八个章节,涉及 面试笔试经验技巧.PHP 基础知识.PHP 进阶知识,PHP 面向对象 ...