Java định nghĩa 4 mức độ reference strength (độ mạnh tham chiếu) quyết định khi nào object được Garbage Collector (GC) thu hồi. Mạnh nhất → Yếu nhất: Strong > Soft > Weak > Phantom.
1. Strong Reference (Tham chiếu mạnh) – Mặc định
- Tạo bằng:
Object obj = new Object(); - Object không bao giờ bị GC thu hồi miễn là strong reference còn tồn tại.
- Chỉ bị thu hồi khi reference = null hoặc ra khỏi scope.
public class StrongRefDemo {
public static void main(String[] args) {
Demo obj = new Demo(); // Strong reference
obj = null; // Bỏ strong reference → eligible for GC
}
}
class Demo { /* ... */ }
2. Weak Reference (Tham chiếu yếu) – java.lang.ref.WeakReference
- GC thu hồi object ở mọi GC cycle (không chờ memory pressure).
- Dùng cho:
WeakHashMap(key weak), listener registry, canonicalizing maps. - Tạo:
WeakReferenceref = new WeakReference<>(obj); ref.get()trả về object hoặc null nếu đã GC.
import java.lang.ref.WeakReference;
public class WeakRefDemo {
public static void main(String[] args) {
Demo obj = new Demo();
obj.display(); // Hello
WeakReference weakRef = new WeakReference<>(obj);
obj = null; // Chỉ còn weak reference
System.gc(); // Yêu cầu GC
try { Thread.sleep(100); } catch (InterruptedException e) {}
Demo retrieved = weakRef.get();
if (retrieved != null) retrieved.display();
else System.out.println("Object đã bị GC reclaim");
}
}
class Demo { void display() { System.out.println("Hello"); } }
3. Soft Reference (Tham chiếu mềm) – java.lang.ref.SoftReference
- GC chỉ thu hồi khi JVM sắp OOM (OutOfMemoryError).
- Thích hợp: Cache (image, parsed data, computed results) – tự động evict khi memory áp lực.
- Cũng có thể dùng
ReferenceQueueđể cleanup.
import java.lang.ref.SoftReference;
public class SoftRefDemo {
public static void main(String[] args) {
Demo obj = new Demo();
obj.display();
SoftReference softRef = new SoftReference<>(obj);
obj = null;
System.out.println("Before GC: " + softRef.get()); // Object còn lại
// Giả lập memory pressure (khó kiểm soát chính xác)
System.gc();
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("After GC: " + softRef.get()); // Vẫn có thể còn (nếu memory đủ)
}
}
4. Phantom Reference (Tham chiếu ảo) – java.lang.ref.PhantomReference
- Object đã finalized (nếu có) nhưng chưa bị reclaim vật lý.
phantomRef.get()LUÔN TRẢ VỀ NULL – không thể revive object.- BẮT BUỘC đăng ký với
ReferenceQueue. - Khi object phantom-reachable → reference được enqueue vào queue.
- Dùng cho: Pre-mortem cleanup (giải phóng native memory, file handle, off-heap resource) – thay thế
finalize().
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class PhantomRefDemo {
public static void main(String[] args) throws InterruptedException {
ReferenceQueue queue = new ReferenceQueue<>();
Demo obj = new Demo();
PhantomReference phantomRef = new PhantomReference<>(obj, queue);
System.out.println("phantomRef.get() = " + phantomRef.get()); // null
obj = null;
System.gc();
// Chờ enqueue (blocking)
PhantomReference extends Demo> ref = (PhantomReference extends Demo>) queue.remove(3000);
if (ref != null) {
System.out.println("Object phantom reachable! Cleanup native resources here.");
// cleanup code...
}
}
}
class Demo { /* native resource handle */ }
So sánh tổng hợp
| Loại | GC Reclaim | get() | ReferenceQueue | Use Case Chính |
|---|---|---|---|---|
| Strong | Không (khi reachable) | Object | Không | Biến thông thường |
| Soft | Khi JVM cần memory (OOM imminent) | Object / null | Optional | Memory-sensitive Cache |
| Weak | Mọi GC cycle | Object / null | Optional | WeakHashMap, Listeners, Canonicalizing |
| Phantom | Sau finalize, trước reclaim | Luôn null | Bắt buộc | Pre-mortem cleanup (native, off-heap) |
Cleaner API (Java 9+) – Thay thế PhantomReference dễ dùng hơn
import java.lang.ref.Cleaner;
public class CleanerDemo {
private static final Cleaner cleaner = Cleaner.create();
static class NativeResource implements Runnable {
private final long handle;
NativeResource(long h) { this.handle = h; }
public void run() {
// Cleanup native resource
System.out.println("Freeing native handle: " + handle);
}
}
public static void main(String[] args) {
NativeResource res = new NativeResource(123);
Cleaner.Cleanable cleanable = cleaner.register(res, res);
// Khi res bị GC → run() được gọi tự động
res = null;
System.gc();
}
}
Tóm tắt chọn lựa
- Strong: Mặc định, hầu hết trường hợp.
- Soft: Cache có thể tái tạo, muốn giữ lâu nếu memory cho phép.
- Weak: Metadata gắn với object (key map, listener), object có thể đi bất cứ lúc nào.
- Phantom/Cleaner: Cleanup tài nguyên native/off-heap, thay thế finalize().