2.Java内存溢出程序举例
OutOfMemoryError: Java heap space
import java.util.ArrayList;
import java.util.List;
/**
-Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError
**/
public class JVMTest {
static class OOM{}
public static void main(String[] args) {
List<OOM> list = new ArrayList<OOM>();
while(true){
list.add(new OOM());
}
}
}
打印结果:
java.lang.OutOfMemoryError: Java heap space Dumping heap to
java_pid1948.hprof … Heap dump file created [27965238 bytes in 0.084
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
JVMTest.main(JVMTest.java:11)
生成的.hprof文件默认在对应工程下面。可以使用如下语句来指定生成的.hprof文件路径及在遇到OnOutOfMemoryError时执行的linux命令。
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/heapdump.hprof
-XX:OnOutOfMemoryError =“sh ~/cleanup.sh”
StackOverflowError
/**
*
* @author x
* -Xss128K
*/
public class JVMTest {
private int stackLength = 1;
public void stackLeak(){
stackLength++;
stackLeak();
}
public static void main(String[] args) {
JVMTest jvmTest = new JVMTest();
try {
jvmTest.stackLeak();
} catch (Exception e) {
System.out.println("Stack length:" + jvmTest.stackLength);
throw(e);
}
}
}
打印结果:
Exception in thread “main” java.lang.StackOverflowError at
JVMTest.stackLeak(JVMTest.java:13) at
JVMTest.stackLeak(JVMTest.java:14) at
JVMTest.stackLeak(JVMTest.java:14) at
JVMTest.stackLeak(JVMTest.java:14) at
JVMTest.stackLeak(JVMTest.java:14) at
JVMTest.stackLeak(JVMTest.java:14) at
JVMTest.stackLeak(JVMTest.java:14)
OutOfMemoryError: Metaspace
import java.util.ArrayList;
import java.util.List;
/**
*
* @author x
* -XX:MaxMetaspaceSize=512K -XX:MetaspaceSize=512K
*/
public class JVMTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
int i = 0;
while(true){
list.add(String.valueOf(i++).intern());
}
}
}
打印
Error occurred during initialization of VM OutOfMemoryError: Metaspace
java.lang.OutOfMemoryError 本地内存
import java.lang.reflect.Field;
import sun.misc.Unsafe;
/**
* VM Args: -Xmx20M -XX:MaxDirectMemorySize=10M
* @author x
*/
public class DirectMemoryOOM {
private static final int _1MB = 1024 * 1024;
@SuppressWarnings("restriction")
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
Field unsafeField = Unsafe.class.getDeclaredFields()[0];
unsafeField.setAccessible(true);
Unsafe unsafe = null;
unsafe = (Unsafe) unsafeField.get(null);
while (true){
unsafe.allocateMemory(_1MB);
}
}
}
打印结果:
Exception in thread “main” java.lang.OutOfMemoryError at
sun.misc.Unsafe.allocateMemory(Native Method) at
DirectMemoryOOM.main(DirectMemoryOOM.java:18)
本地内存溢出一个明显的特征是在Heap Dump文件中不会看见明显的异常,如果发现OOM之后Dump文件很小,而程序中直接或间接使用了NIO,那就可以考虑检查一下是否是这方面的原因导致。