Skip to content

Commit 90ace8b

Browse files
committed
feat(PhantomDemo1): add PhantomReference + ReferenceQueue cleanup example
What - Added `PhantomDemo1` to demonstrate PhantomReference lifecycle. - Created `NativeResource` wrapped in PhantomReference with ReferenceQueue. - Showed that `pr.get()` always returns null. - Dropped strong reference, triggered GC, and checked ReferenceQueue. - Printed cleanup message if PhantomReference enqueued. Why - To illustrate safe post-GC cleanup without relying on finalizers. - PhantomReference is essential for releasing non-Java resources (native memory, file handles). - Complements SoftReference (caching) and WeakReference (maps/listeners). How - Step 1: Define `NativeResource` with `id`. - Step 2: Instantiate and wrap in `PhantomReference<>(res, queue)`. - Step 3: Print `pr.get()` → always null. - Step 4: Nullify `res`, suggest GC via `System.gc()`. - Step 5: Sleep briefly for GC. - Step 6: Poll ReferenceQueue; if enqueued, log cleanup and call `clear()`. Logic - Inputs: new `NativeResource(1)`. - Outputs: - Console log before GC: `before nulling res, pr.get() = null`. - After GC, either: - `"Phantom enqueued — do cleanup now for ..."`, or - `"No phantom enqueued yet."`. - Flow: 1. Strong + phantom refs exist. 2. Strong ref dropped → object phantom-reachable. 3. GC clears object → PhantomReference enqueued. 4. Application detects and performs cleanup. - Complexity: O(1) for ReferenceQueue operations. - Non-determinism: GC may or may not run immediately, so queue.poll() may return null. Real-life applications - Safe cleanup of DirectByteBuffers (off-heap memory). - Closing file handles or sockets after object reclamation. - Resource tracking in JVM-managed frameworks. Notes - PhantomReference is the lowest-level reference type in Java’s hierarchy. - Unlike soft/weak refs, `get()` always returns null. - Cleanup must be done through ReferenceQueue. Signed-off-by: https://github.com/Someshdiwan <[email protected]>
1 parent a2b9af8 commit 90ace8b

File tree

1 file changed

+40
-0
lines changed
  • Section 25 Collections Frameworks/Map Interface/Garbage Collection/SoftReference vs WeakReference vs PhantomReference/src

1 file changed

+40
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import java.lang.ref.PhantomReference;
2+
import java.lang.ref.Reference;
3+
import java.lang.ref.ReferenceQueue;
4+
5+
public class PhantomDemo1 {
6+
static class NativeResource {
7+
private final int id;
8+
NativeResource(int id) { this.id = id; }
9+
@Override public String toString() { return "NR#" + id; }
10+
}
11+
12+
public static void main(String[] args) throws InterruptedException {
13+
ReferenceQueue<NativeResource> queue = new ReferenceQueue<>();
14+
NativeResource res = new NativeResource(1);
15+
16+
// create phantom ref (get() returns null)
17+
PhantomReference<NativeResource> pr = new PhantomReference<>(res, queue);
18+
19+
System.out.println("before nulling res, pr.get() = " + pr.get()); // always null
20+
21+
// drop strong ref
22+
res = null;
23+
24+
// suggest GC
25+
System.gc();
26+
Thread.sleep(200);
27+
28+
// check queue - if enqueued, we can run cleanup
29+
Reference<? extends NativeResource> r = queue.poll();
30+
if (r != null) {
31+
System.out.println("Phantom enqueued — do cleanup now for " + r);
32+
// free native memory / close handles here
33+
r.clear();
34+
} else {
35+
System.out.println("No phantom enqueued yet.");
36+
}
37+
}
38+
}
39+
40+
// PhantomReference + ReferenceQueue example (cleanup).

0 commit comments

Comments
 (0)