Skip to content

Commit e949956

Browse files
committed
feat(GCDemo1): add demo of WeakReference, strong refs, and GC with ReferenceQueue
What - Added `GCDemo1` class with nested `Big` class (allocates ~1MB array). - Created: • Strong reference → Big#1 • WeakReference (weak1) → Big#2 (no strong refs) • WeakReference (weak2) → Big#1 (also held by strong initially) - Used `ReferenceQueue<Big>` to capture cleared weak references. - Printed object states before and after `System.gc()` and checked queue. Why - To demonstrate how JVM garbage collector handles strong vs weak references. - Showed how weak references are cleared when no strong refs exist. - Illustrated how ReferenceQueue helps detect when referents are reclaimed. - Useful for cache design and avoiding memory leaks. How - Before GC: strong → Big#1 weak1.get() → Big#2 weak2.get() → Big#1 refQueue empty - After nulling strong and running GC: weak1.get() → null (Big#2 reclaimed) weak2.get() → null (Big#1 reclaimed) refQueue contains [weak1, weak2] - Printed enqueued weak refs from refQueue. Logic - Inputs: - Instantiated Big objects with ids 1 and 2. - Outputs: - Console logs showing object states before/after GC. - Enqueued references from ReferenceQueue. - Flow: 1. Create strong + weak refs. 2. Print pre-GC states. 3. strong = null. 4. Call System.gc() and sleep briefly. 5. Print post-GC states. 6. Drain ReferenceQueue to show cleared refs. - Constraints: - GC behavior not strictly guaranteed; System.gc() is only a hint. - Complexity: - O(1) reference checks, O(n) to drain queue (n = cleared refs). Real-life applications - WeakReference used in caches where objects can be reclaimed automatically. - Helps avoid memory leaks when object lifetime should not be strictly managed. - ReferenceQueue allows cleanup tasks when objects are collected. Notes - Strong refs keep objects alive. - Weak refs do not prevent GC. - ReferenceQueue signals GC-cleared refs. - Demo shows memory pressure handling and lifecycle of weak references. Signed-off-by: https://github.com/Someshdiwan <[email protected]>
1 parent 2fb08a5 commit e949956

File tree

1 file changed

+139
-0
lines changed
  • Section 25 Collections Frameworks/Map Interface/Garbage Collection/src

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import java.lang.ref.Reference;
2+
import java.lang.ref.ReferenceQueue;
3+
import java.lang.ref.WeakReference;
4+
5+
public class GCDemo1 {
6+
// A simple object with a moderately large byte[] so GC will likely reclaim it under pressure.
7+
static class Big {
8+
private final byte[] data;
9+
private final int id;
10+
11+
Big(int id) {
12+
this.id = id;
13+
// allocate ~1MB so GC can notice memory pressure in small demos
14+
this.data = new byte[1_000_000];
15+
}
16+
17+
@Override
18+
public String toString() {
19+
return "Big#" + id;
20+
}
21+
}
22+
23+
public static void main(String[] args) throws Exception {
24+
ReferenceQueue<Big> refQueue = new ReferenceQueue<>();
25+
26+
// 1) Strong reference: will keep object alive until cleared
27+
Big strong = new Big(1);
28+
29+
// 2) WeakReference to a freshly created Big(2) — no strong ref -> eligible immediately
30+
WeakReference<Big> weak1 = new WeakReference<>(new Big(2), refQueue);
31+
32+
// 3) WeakReference to the object currently held by "strong"
33+
WeakReference<Big> weak2 = new WeakReference<>(strong, refQueue);
34+
35+
System.out.println("Before GC:");
36+
System.out.println(" strong = " + strong);
37+
System.out.println(" weak1.get() = " + weak1.get());
38+
System.out.println(" weak2.get() = " + weak2.get());
39+
System.out.println(" refQueue.poll() = " + refQueue.poll());
40+
System.out.println();
41+
42+
// Make the previously-strong object eligible for GC by removing the strong ref
43+
strong = null;
44+
45+
// Suggest GC and wait a bit — JVM may run GC and clear weak refs
46+
System.gc();
47+
Thread.sleep(800);
48+
49+
System.out.println("After GC:");
50+
System.out.println(" weak1.get() = " + weak1.get()); // most likely null (no strong refs ever)
51+
System.out.println(" weak2.get() = " + weak2.get()); // likely null now (strong was nulled)
52+
System.out.println();
53+
54+
// Inspect reference queue to see which weak references were enqueued after GC
55+
Reference<? extends Big> enqueued;
56+
while ((enqueued = refQueue.poll()) != null) {
57+
System.out.println("Reference enqueued (cleared by GC): " + enqueued);
58+
}
59+
60+
System.out.println("\nDemo finished.");
61+
}
62+
}
63+
64+
/*
65+
1. Purpose of Code:
66+
- Yeh program dikhata hai ki JVM Garbage Collector **strong** aur **weak** references ko kaise treat karta hai.
67+
- `WeakReference` wali objects strong reference ke bina garbage collect ho sakti hain.
68+
- Agar object GC ke dwara clear hoti hai, toh weak reference ko `ReferenceQueue` me daal diya jata hai.
69+
70+
2. Important Parts:
71+
- Big class: ek heavy object (~1MB array) banaya gaya hai taaki GC ko pressure dikhe.
72+
- strong reference: object ko alive rakhta hai jab tak null nahi hota.
73+
- weak1: ek object ke liye jo sirf weakly referenced hai, aur jaldi collect ho jaayega.
74+
- weak2: initially same object ko point karta hai jo strong bhi refer kar raha hai.
75+
- ReferenceQueue: jab weak reference clear hota hai, JVM usko queue me enqueue kar deta hai.
76+
77+
3. Execution Flow:
78+
79+
- Before GC:
80+
strong -> Big#1
81+
weak1.get() -> Big#2
82+
weak2.get() -> Big#1
83+
refQueue = empty
84+
85+
- After `strong = null;` + GC:
86+
strong -> null
87+
weak1.get() -> null (collected)
88+
weak2.get() -> null (collected)
89+
refQueue -> [weak1, weak2]
90+
91+
4. ASCII Diagram:
92+
93+
Before GC:
94+
-------------------------
95+
strong ---> [Big#1]
96+
weak1 -X-> [Big#2]
97+
weak2 -X-> [Big#1]
98+
refQueue: empty
99+
-------------------------
100+
101+
After GC:
102+
-------------------------
103+
strong -> null
104+
weak1.get() -> null
105+
weak2.get() -> null
106+
refQueue: [weak1, weak2]
107+
-------------------------
108+
109+
5. Quick Recap:
110+
✔ Strong reference: object ko GC se bachata hai.
111+
✔ Weak reference: GC kabhi bhi clear kar sakta hai agar strong ref na ho.
112+
✔ ReferenceQueue: pata lagta hai ki object collect ho gaya.
113+
✔ `System.gc()` sirf JVM ko suggestion deta hai (force nahi).
114+
115+
Practical Use:
116+
- Weak references caches me use hote hain.
117+
- Yeh memory leaks prevent karte hain jab object ki lifetime app ke control me nahi hoti.
118+
119+
Initially (before pulling strong):
120+
Heap:
121+
[ Big#1 ] <-- strong
122+
[ Big#2 ] <-- only weak1 (no strong)
123+
References:
124+
strong -> Big#1
125+
weak1 -X-> Big#2 (weak)
126+
weak2 -X-> Big#1 (weak)
127+
refQueue: empty
128+
129+
130+
After strong = null and GC:
131+
Heap:
132+
[ <free> ] (Big#1 reclaimed)
133+
[ <free> ] (Big#2 reclaimed)
134+
References:
135+
strong -> null
136+
weak1.get() -> null
137+
weak2.get() -> null
138+
refQueue: [ weak1, weak2 ] (weak refs enqueued)
139+
*/

0 commit comments

Comments
 (0)