jvm内存模型分析(5)堆内存溢出以及分析

2019 精帖
0 279

jvm内存模型分析(5)堆内存溢出以及分析

1.模拟堆内存溢出代码

package test;

import java.util.ArrayList;
import java.util.List;
/**
 * VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
 * @author zzm
 */
public class HeapOOM {
	static class OOMObject {
	}
	public static void main(String[] args) {
		List<OOMObject> list = new ArrayList<OOMObject>();
		while (true) {
			list.add(new OOMObject());
		}
	}
}

2.jvm启动参数设置

        目的是因为jvm虚拟机初始的内存还是挺大的,所以缩小堆内存,来快速实现内存溢出。

-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

QQ截图20190302191012.png

3.程序运行结果:

java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid8452.hprof ...
Heap dump file created [27943398 bytes in 0.070 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Unknown Source)
	at java.util.Arrays.copyOf(Unknown Source)
	at java.util.ArrayList.grow(Unknown Source)
	at java.util.ArrayList.ensureExplicitCapacity(Unknown Source)
	at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
	at java.util.ArrayList.add(Unknown Source)
	at test.HeapOOM.main(HeapOOM.java:15)

QQ截图20190302191111.png



4.分析:

        Java堆用于存储对象实例,只要不断地创建对象,并且保证 GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。

        代码中限制Java堆的大小为20MB,不可扩展(将堆的最小值-Xms参数与最大值-Xmx参数设置为一样即可避免堆自动扩展),通过参数-XX+Heap DumpOnOutofMemoryError可以让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便事后进行分析。


        程序运行结束以后刷新文件夹会出现一个快照文件


QQ截图20190302191314.png


        然后利用eclipse memory analyzer内存分析工具,进行分析,定位出现问题的类,和方法,从而找到解决问题的方法


QQ截图20190302191533.png

QQ截图20190302191641.png

QQ截图20190302192011.png


        从中我们可以发现,在主线程中,也就是main函数中创建了大量的 OOMObject 对象,并且对象被list集合应用,无法被释放,导致内存溢出。从而定位到问题。


留言(0)
加载更多
猜你喜欢