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).
// 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):
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".
Java memory leak: an object is still referenced but no longer needed — GC cannot collect it (GC only reclaims unreachable objects).
// Static collection — classic leak
static List<Object> list = new ArrayList<>();
list.add(obj); // never removed → object lives foreverCommon causes:
- Unclosed resources: file handles, DB connections, network sockets.
- Unregistered listeners: the subject still holds a reference.
- Unbounded static collections (caches with no eviction).
- ThreadLocal not remove()-d — thread pools reuse threads → ThreadLocal keeps old objects.
- Inner classes implicitly retain the enclosing object.
- String pool — too many intern() calls.
Prevention:
- try-with-resources for AutoCloseable (files, DB connections):
try (var stmt = conn.prepareStatement(sql)) { /* ... */ } // auto close- Unregister listeners in
@PreDestroyordestroy(). - Caches need an eviction policy (Caffeine, Guava).
WeakReference/SoftReferencefor cache values.- ThreadLocal: always
remove()in a finally.
Debug: heap dump (jmap -dump) → Eclipse MAT, look at "Leak Suspects".