Memory leak Java: object vẫn còn reference nhưng không còn cần — GC không thể collect (vì nguyên tắc GC: chỉ thu hồi object unreachable).
java
// Static collection — leak điển hình
static List<Object> list = new ArrayList<>();
list.add(obj); // không bao giờ remove → object sống mãiNguyên nhân phổ biến:
- Unclosed resource: file handle, DB connection, network socket.
- Listener không unregister: subject giữ reference đến listener.
- Static collection phình mãi (cache không evict).
- ThreadLocal không remove() — thread pool reuse thread → ThreadLocal giữ object cũ.
- Inner class giữ ref ngầm đến enclosing object.
- String pool — intern() quá nhiều String.
Phòng tránh:
- try-with-resources cho AutoCloseable (file, DB connection):
java
try (var stmt = conn.prepareStatement(sql)) { /* ... */ } // auto close- Unregister listener trong
@PreDestroyhoặcdestroy(). - Cache có eviction policy (Caffeine, Guava).
WeakReference/SoftReferencecho cache.- ThreadLocal: luôn
remove()trong finally.
Debug: heap dump (jmap -dump) → Eclipse MAT phân tích "Leak Suspects".