使用小例子来练习如何分析内存溢出
1.制造事故
这里直接上代码了 就是使劲往
List
中存内容,最后撑爆内存
package test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class MemoryOut {
public static final Integer K = 4*1024;
public static void main(String[] args) throws InterruptedException {
System.out.println("最大内存(byte):" + Runtime.getRuntime().maxMemory());
List<byte[]> data = new ArrayList<>();
for (int i = 0; i < K; i++) {
System.out.println("JVM写入数据" + (i + 1)*10 + "M");
data.add(new byte[1024 * 1024 * 10]);
System.out.println("当前剩余内存(byte):" + Runtime.getRuntime().freeMemory());
TimeUnit.SECONDS.sleep(1);
}
}
}
可以看出来我最大往内存中存入
40G
的内容,一般都会溢出的吧,运行后不负众望,当然我们可以设置VM options
来限制下堆的大小,这样就不要等太久了,还要设置下当内存溢出后自动导出dump
文件,设置入下
-Xmx512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=F:\jvmdmp
-Xmx512m
表示堆内存最大512MB
-XX:+HeapDumpOnOutOfMemoryError
JVM发生OOM
时,自动生成DUMP
文件
-XX:HeapDumpPath=F:\jvmdmp
设置导出的dump
文件地址,不过这里我以为是个路径,其实是名字
使用Jvisualvm
观察内存
image.png
我们可以看到使用的堆内存不断增加,总的堆内存不断扩容,直到我们设置的最大值,然后就
OOM
了
下载并使用mat
分析dump
文件
image.png
MAT
其实是eclipse
里的一个插件,不过现在大多使用idea
,幸好它也有个独立版本
下载地址如下
https://www.eclipse.org/mat/downloads.php
这里需要选择红框中的Windows (x86_64)
进入后记得选择下镜像,默认是韩国的,下不动……
image.png
下载后解压直接打开MemoryAnalyzer.exe
即可。
加载导出的dump
文件
可能导出的文件没有后缀,但是丝毫不影响咱们打开
image.png加载后可以发现,贴心的告诉了我们哪里可能存在问题
点击下detail
,发现罪魁祸首已经出来了,这样就看出来哪边导致内存溢出啦
网友评论