目标:生成dump文件,用eclipseMemoryAnalyzer工具分析dump文件的情况
生产环境做法:用jmap命令生成dump文件,再导入eclipseMemoryAnalyzer工具分析查看
jmap -dump:format=b,file=tomcat1_15767_dump.bin 15767
jmap命令用法:http://docs.oracle.com/javase/7/docs/technotes/tools/share/jmap.html
在里测试就用ecipse插件方式生成
1:下载工eclipseMemoryAnalyzer工具和插件
http://www.eclipse.org/mat/downloads.php
eclipse插件安装地址:
Update Site: http://download.eclipse.org/mat/1.6.1/update-site/
2:建个空项目,来搞事情,让他内存溢出,只要几行代码。
package stu.org.test1;
import java.util.ArrayList;
import java.util.List;
public class Main1 {
public class testOOM {
private long l;
private double d;
}
public static void main(String[] args) {
List<testOOM> list = new ArrayList<>();
int i = 0;
while (true) {
Main1 main = new Main1();
list.add(main.new testOOM());
System.out.println("hello world>>>" + (i++));
}
}
}
配置jvm运行参数
-Xmx10M -Xms10M -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
3:运行代码
output:
....省略
hello world>>>160010
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to java_pid9092.hprof ...
Heap dump file created [14275544 bytes in 0.059 secs]
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at stu.org.test1.Main1.main(Main1.java:20)
在项目目录中会生成一个文件:java_pid9092.hprof
打开安装好的MemoryAnalyzer,导入文件,
重点是看这几个分析:
Actions
Histogram: Lists number of instances per class[列出了每个类的实例数量]
Dominator Tree: List the biggest objects and what they keep alive.[最大的对象列表和他们保持活的。]
Top Consumers: Print the most expensive objects grouped by class and by package.[打印最大的对象按类分组和包。]
Leak Suspects: includes leak suspects and a system overview[内存泄漏疑点和一个系统的概述]
分析结果如下:
这个对象160012个, 暂用7680576/1024/10214=7.32MB
这个线程局部变量的总大小8321464/1024/10214=7.93MB ,暂比95.2%,还有一些是jvm内部需要的内存,而jvm我最大只分了10MB,导致内存不够用就报java.lang.OutOfMemoryError了
参考文档:https://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/