Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

Memory Leak ใน Java: สาเหตุ ตัวอย่าง และการป้องกัน

Memory Leak คืออะไร?

ใน Java มี Garbage Collector (GC) จัดการหน่วยความจำอัตโนมัติ แต่ Memory Leak เกิดขึ้นเมื่อ:

  • ออบเจกต์ยังมี reference ชี้อยู่ (ไม่ได้ถูกปล่อย)
  • แต่โปรแกรมไม่ได้ใช้ออบเจกต์นั้นต่อไปแล้ว
  • GC จึงไม่สามารถเก็บขยะออบเจกต์นั้นได้
  • สะสมมากพอ → OutOfMemoryError: Java heap space

ตัวอย่าง: Heap Exhaustion

import java.util.Vector; 

public class Demo { 
    public static void main(String[] args) { 
        Vector v1 = new Vector<>(314_567); 
        Vector v2 = new Vector<>(784_324_678); // ใหญ่เกินไป!
        System.out.println("บรรทัดนี้ไม่เคยทำงาน"); 
    } 
}

ผลลัพธ์

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
    at java.base/java.util.Vector.<init>(Vector.java:142) 
    at Demo.main(Demo.java:7)

คำอธิบาย

พยายามจัดสรร Vector ขนาด 784 ล้าน elements → เกิน heap size → JVM โยน OutOfMemoryError ก่อนถึงบรรทัดสุดท้าย

สาเหตุ Memory Leak จริงๆ (Common Causes)

1. Static Collections เก็บออบเจกต์ไม่เคย clear

// อันตราย!
static List cache = new ArrayList<>(); 
public void add(Object o) { cache.add(o); } // ไม่มีการลบออกเลย

2. Listener/Callback ไม่ถูก deregister

button.addActionListener(listener); 
// ต้องมี button.removeActionListener(listener) เมื่อไม่ใช้แล้ว

3. ThreadLocal ไม่ถูก remove

ThreadLocal tl = new ThreadLocal<>(); 
tl.set(conn); 
// ต้อง tl.remove() เมื่อจบการใช้งาน มิฉะะ leak ใน thread pool

4. Cache ไม่มีขนาดจำกัด (unbounded)

// ใช้ LinkedHashMap + removeEldestEntry หรือ Caffeine/Guava Cache แทน

การป้องกันและแก้ไข

  • ตั้งค่า -Xmx ให้เพียงพอ แต่ไม่ใช่แก้ root cause
  • ใช้ WeakReference / SoftReference สำหรับ cache
  • ปิด resource (try-with-resources): Stream, Connection, File
  • ตั้งค่า -XX:+HeapDumpOnOutOfMemoryError เพื่อวิเคราะห์ heap dump
  • ใช้ Profiler: VisualVM, JProfiler, YourKit, Java Mission Control
  • Code review หา static collections, listeners, ThreadLocal ที่ไม่ clean up

เครื่องมือวินิจฉัย

# Heap dump เมื่อ OOM
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprof MyApp

# วิเคราะห์ด้วย jhat หรือ Eclipse MAT
jhat /tmp/heap.hprof