1. 测试代码
public class Person {
private String name;
/**
* @return String return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
public class OutOfMemoryTest {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
while (true) {
personList.add(new Person());
}
}
}
2. 运行OutOfMemoryTest
java -XX:+HeapDumpOnOutOfMemoryError -Xms20m -Xmx20m org.glasshouse.seed.javase.jvm.oom.OutOfMemoryTest
运行结果:
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid38032.hprof ...
Heap dump file created [34587052 bytes in 0.253 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
at java.util.Arrays.copyOf(Arrays.java:3181)
at java.util.ArrayList.grow(ArrayList.java:261)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
at java.util.ArrayList.add(ArrayList.java:458)
at org.glasshouse.seed.javase.jvm.oom.OutOfMemoryTest.main(OutOfMemoryTest.java:11)
3. 结果分析
使用Eclipse Memory Analyzer工具打开java_pid38032.hprof文件。
内存占用分析.pngShallow Heap Size
指对象自身所占用的内存大小,不包含其引用的对象所占的内存大小。
a、数组类型
数组元素对象所占内存的大小总和。
b、非数组类型
对象与它所有的成员变量大小的总和。当然这里面还会包括一些java语言特性的数据存储单元。
Retained Heap Size
当前对象大小+当前对象可直接或间接引用到的对象的大小总和。
(间接引用的含义:A->B->C, C就是间接引用)
换句话说,Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。
不过,释放的时候还要排除被GC Roots直接或间接引用的对象。他们暂时不会被被当做Garbage。
网友评论