jstack -- 用于分析虚拟机当前线时刻的 线程快照(当前执行的堆栈信息),对象的信息;
值得关注的线程:
死锁,Deadlock(重点关注)
执行中,Runnable
等待资源,Waiting on condition(重点关注)
等待获取监视器,Waiting on monitor entry(重点关注)
暂停,Suspended
对象等待中,Object.wait() 或 TIMED_WAITING
阻塞,Blocked(重点关注)
停止,Parked
jstat--可以观察到classloader,compiler,gc相关信息
-class:统计class loader行为信息
-compile:统计编译行为信息
-gc:统计jdk gc时heap信息
jstat -gc 2083 2000 20(每隔2秒监控一次,共做10)
jmap -- 用于生成堆转储快照,生成dum p文件, 还可以用于 堆信息查询。
导出整个JVM 中内存信息,查看对象的内存占用状况,引用关系,分析内存泄露
jmap -dump:format=b,file=文件名 [pid]
基于dump文件进行分析
Histogram可以列出内存中的对象,对象的个数以及大小。
Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。
Top consumers通过图形列出最大的object。
Leak Suspects通过MA自动分析泄漏的原因。
Histogram
Class Name : 类名称,java类名
Objects : 类的对象的数量,这个对象被创建了多少个
Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用 (直接引用)
Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的总和 (间接引用)
注:可以去list objects -> with incoming refrences 查看引用的对象,
1:list objects ->with incoming refs将列出该类的实例:
2:Path to GC Roots-->exclue all phantom/weak/soft etc. reference:用这个方法可以快速找到某个对象的GC Root,一个存在 GC Root的对象是不会被 GC回收掉的
对比Histogram
为查找内存泄漏,通常需要两个 Dump结果作对比,打开 Navigator History面板,将两个表的 Histogram结果都添加到 Compare Basket中去 ,然后点击Compare the Results (视图右上角的红色"!"图标)。
Leak Suspects
直接查看现在存在最大的几个问题,可以查看被实例化最多的对象,再结合程序查看。
查看某一个对象占用的内存空间
JavaBasics -> open in dominator tree;
http://blog.csdn.net/aaa2832/article/details/19419679/
http://blog.csdn.net/rachel_luo/article/details/8992461
举例一个典型的分析内存泄漏的过程:
1. 使用 Heap查看当前堆大小为 23.00M
2. 添加一个页后堆大小变为 23.40M
3. 将添加的一个页删除,堆大小为 23.40M
4. 多次操作,结果仍相似,说明添加/删除页存在内存泄漏 (也应注意排除其它因素的影响)
5. Dump 出操作前后的 hprof 文件 (1.hprof,2.hprof),用 mat打开,并得到 histgram结果
6. 使用 HomePage字段过滤 histgram结果,并列出该类的对象实例列表,看到两个表中的对象集合大小不同,操作后比操作前多出一个 HomePage,说明确实存在泄漏
7. 将两个列表进行对比,找出多出的一个对象,用查找 GC Root的方法找出是谁串起了这条引用线路,定位结束
PS :
· 很多时候堆增大是 Bitmap引起的,Bitmap在 Histogram中的类型是 byte [],对比两个 Histogram中的 byte[] 对象就可以找出哪些 Bitmap有差异
· 多使用排序功能,对找出差异很有用