[转帖]使用JProfiler进行内存分析
Posted jinanxiaolaohu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[转帖]使用JProfiler进行内存分析相关的知识,希望对你有一定的参考价值。
使用JProfiler进行内存分析
运行环境:
Tomcat6,jdk6,JProfiler8
内存泄漏的现象:
1. 在服务器中执行某些批量操作的时候,发现内存只升不降;就算gc后,内存也不能被完全释放;
2. 除非重启tomcat服务器,内存永远不会被释放,反复执行这些操作,会导致无可用内存,tomcat死掉;
使用JProfiler检查内存泄漏的步骤:
1. 初始化检验环境:
切换到“Live Memory-->All Objects”标签,可以看到当前tomcat中的对象情况,注意jprofiler其他版本可能位置不一样.
在执行操作前,需要先F4,运行“Run GC”,使jvm进行内存回收清理无效的对象.为了便于比较内存的增长情况,可以点击右键--->"Mark Current",
来将当前内存使用情况作为参照;点击后会显示“Difference”列,该列会列出对象数量的变化和变化比率
2.打开内存记录:
点击“Start Recordings”按钮,开始记录。执行这步的主要目的是为下面“Heap Walker”设置一个监控区间;如果不记录的话“Heap Walker”将分析jvm虚拟机的所有内存,即耗时又不能准确的发现内存泄漏的原因。
3. 执行操作,执行gc;
使用压力工具访问被测应用,执行完之后再次F4进行GC----这样是为了消除可以回收的对象。执行内存回收后,仍然存在于内存中的对象有可能是泄漏的对象。如下图instance count中红色的部门为不能回收的对象,difference列列出了增加的对象数量和增。以String为例,在该操作中增加了31751个对象增幅达到了14%,随后会在HeapWalker中观察这些对象,分析哪些对象是泄漏的。一般引起泄漏的对象包括:String、char[]、HashMap、Concurrenthashmap等,这类对象需要重点关注下;
4. 关闭内存记录:
点击“Stop Recordings”关闭内存记录,告诉jProfiler把这段记录作为分析对象;
5. 找到增加迅速的对象类型,打开HeapWalker:
在视图中找到增长快速的对象类型,本例Concurrenthashmap的增长速度很快。在memory视图中找到Concurrenthashmap---点右键----选择“Show Selectiion In Heap Walker”,切换到HeapWarker 视图;切换前会弹出选项页面,注意一定要选择“Select recorded objects”,这样Heap Walker会在刚刚的那段记录中进行分析;否则,会分析tomcat的所有内存对象,这样既耗时又不准确;
6. 在HeapWalker中,找到泄漏的对象;
HeapWarker 会分析内存中的所有对象,包括对象的引用、创建、大小和数量;
HeapWarker视图下方可以进行页面切换:
通过切换到References页签,可以看到这个类的具体对象实例。
为了在这些内存对象中,找到泄漏的对象(应该被回收),可以在该对象上点击右键,选择“Use Selected Instances”缩小对象范围;
单击OK按钮
7. 通过引用分析该对象:
在References引用页签中,可以看到该对象的的引用关系,可以切换incoming/outcoming,显示引用的类型:
incoming 表示显示这个对象被谁引用;
outcoming 表示显示这个对象引用的其他对象;
选择“Show In Graph”将引用关系使用图形方式展现;
选中该对象,点击“Show Paths To GC Root”,会找到引用的根节点;
在上图中,我们可以发现,这个HashMap Segment对象最终的引用是在ConcurrentHashMap和ReentranLock对象中;
8. 通过创建分析该对象:
如果第7步还不能定位内存泄露的地方,我们可以尝试使用Allocations页签,该页签显示对象是如何创建出来的;
我们可以从创建方法开始检查,检查所有用到该对象的地方,直到找到泄漏位置;
持续学习、持续收获才能带来持续的满足和快乐!
以上是关于[转帖]使用JProfiler进行内存分析的主要内容,如果未能解决你的问题,请参考以下文章
如何在 JProfiler 离线模式下使用触发器进行分析时自动获取保留的内存