内存 异常排查

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


内存 异常排查_第1张图片

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有差异

·        多使用排序功能,对找出差异很有用

你可能感兴趣的:(内存 异常排查)