OutOfMemoryError ถูกโยนโดย JVM เมื่อ JVM ไม่มีหน่วยความจำเพียงพอสำหรับการจัดสรร OutOfMemoryError อยู่ในหมวด Error ในลำดับชั้นของ Exception class hierarchy
การสร้าง OutOfMemoryError
- จัดสรรหน่วยความจำขนาดใหญ่ ซึ่งจะทำให้ heap memory storage หมด
- ทำการจัดสรรหน่วยความจำต่อเนื่อง จนถึงจุดที่ JVM ไม่มีหน่วยความจำพอสำหรับการจัดสรร แล้ว OutOfMemoryError จะถูกโยน
- เมื่อจับ OutOfMemory error ได้แล้ว เราสามารถ log error นั้นได้
ตัวอย่าง
public class OutOfMemoryErrorDemo {
public static void main(String[] args) throws Exception {
int dummyArraySize = 15;
System.out.println("Max JVM memory: " + Runtime.getRuntime().maxMemory());
long memoryConsumed = 0;
try {
long[] memoryAllocated = null;
for(int loop = 0; loop < Integer.MAX_VALUE; loop++) {
memoryAllocated = new long[dummyArraySize];
memoryAllocated[0] = 0;
memoryConsumed += dummyArraySize * Long.SIZE;
System.out.println("Memory Consumed till now: " + memoryConsumed);
dummyArraySize *= dummyArraySize * 2;
Thread.sleep(500);
}
} catch (OutOfMemoryError outofMemory) {
System.out.println("Catching out of memory error");
// Log the information, so that we can generate the statistics
throw outofMemory;
}
}
}
ผลลัพธ์
Max JVM memory: 119537664
Memory Consumed till now: 960
Memory Consumed till now: 29760
Memory Consumed till now: 25949760
Catching out of memory error
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at OutOfMemoryErrorDemo.main(OutOfMemoryErrorDemo.java:9)
ขั้นตอนการหาสาเหตุรากฐานของ OOM
ขั้นตอนที่ 1: สร้าง Heap Dump เมื่อเกิด OutOfMemoryError
เริ่มแอปพลิเคชันด้วย VM argument -XX:+HeapDumpOnOutOfMemoryError จะสั่งให้ JVM สร้าง heap dump เมื่อเกิด OOM
$ java -XX:+HeapDumpOnOutOfMemoryError ...
ขั้นตอนที่ 2: ทำซ้ำปัญหา (Reproduce)
หากไม่สามารถ ทำซ้ำปัญหา ได้ใน สภาพแวดล้อมการพัฒนา (development environment) อาจต้องใช้ สภาพแวดล้อมการผลิต (production environment) เมื่อทำซ้ำปัญหาและแอปพลิเคชันโยน OOM จะสร้างไฟล์ heap dump
ขั้นตอนที่ 3: สืบสวนปัญหาโดยใช้ไฟล์ Heap Dump
ใช้ VisualVM เพื่ออ่าน heap dump file และวินิจฉัยปัญหา VisualVM เป็นโปรแกรมที่ตั้งอยู่ที่ JDK_HOME/bin/jvisualvm ไฟล์ heap dump มีข้อมูลทั้งหมดเกี่ยวกับการใช้หน่วยความจำของแอปพลิเคชัน