我们开发一个测试程序,来模拟OutofMemory情况。
程序很简单,代码如下:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
while(true){
list.add(new String("test"));
}
}
}
我们进入该java文件所在的目录,然后打开控制窗口,进入到该目录。
通过javac编译Test.java文件
再来看我们的test目录
这下子生成了编译之后的.class文件,然后我们来执行它。
运行该程序时设置JVM的堆内存(heapsize)的极限值为10M(-Xmx10m)
如果直接执行这个程序的话,它会直到耗至我们机器上所有的内存才会报错,方便我们进行演示,运行的时候加上-Xmx10m。
运行之后等待一会,如果不想等待这么久的话,还可以将运行内存调整至5M
报错的结果
产生内存溢出的问题,现在我们该如何分析呢?
可以使用Heap Dump。
什么是Heap Dump呢?
一个Heap Dump是指在某个时刻对一个java进程所使用的内存情况的一次快照。也就是在某个时刻把Java进程的内存以某种格式持久化到了磁盘上。
如何生成Head Dump文件?
设置参数: —— -XX:+HeapDumpOnOutOfMemoryError
此参数是帮助生成dump文件,程序启动后直到抛出OOM异常。异常抛出后,在程序的classpath下生成以一个.hprof结尾的文件,如:java_pid4504.hprof,这就是我们需要的dump文件。
我们先看一下该目录,是没有.hprof文件的
加上这个参数我们在运行一次
抛出异常之后
再来看一下test目录
这是我们可以看到一件生成了.hprof文件,在实际生产环境中这个文件会非常大。
之后我们可以用IBM heapAnalyzer来分析该文件。
IBM开发的强大的内存dump分析工具,IBM heapAnalyzer是通过分析OOM后的Java heap dump文件的,通过对dump文件的分析找到可能!!!泄露的点。(注意:这是说的是可能,真正的内存溢出,我们还需要结合程序来进行一个分析)
下载之后只有得到这样的文件(下载方式在底部)
然后运行它
运行之后打开一个这个界面
点击接受
打开文件
选中,然后点击open
我们打开该文件之后
这里说明,有一个对象占用了百分之九十四的空间,可能是它造成的溢出,但是这里说的是可能!具体还要结合具体的程序去分析,到底在那个地方造成的泄露。
实际生产环境中的文件非常大,也不会像这里这么明显,所以还需要在实际生产环境中多多实践!
这套方法还可以在一下程序中使用:
因为他们的底层都是用的jvm,总结一句话,只要底层用jvm,都可以用这套方法。
如何下载 IBM heapAnalyzer ?
百度搜索 IBM heapAnalyzer 找到官网:https://www.ibm.com/developerworks/community/groups/service/html/communityview?communityUuid=4544bafe-c7a2-455f-9d43-eb866ea60091
然后点击这个下载即可
下载之后是一个jar文件,需要在命令窗口运行这个jar文件。