java記憶體溢位程式舉例
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,那就可以考慮檢查一下是否是這方面的原因導致。