Better late than never.
This is not how weak links work. WeakReference -object will always be there, but its get() -method can return the original object or null (if the original object was GC: ed).
This means that your stack will always contain a WeakReference -object.
Here is a detailed test that I conducted (however, it depends on how the JVM executes the GC in the middle, which may or may not happen "on command" - try adding System.gc() : s if it doesnβt):
public static void main(String[] args) { // Set up Object object = new Object(); final WeakReference<Object> weakReference = new WeakReference<>(object); final Stack<WeakReference<Object>> references = new Stack<>(); references.add(weakReference); // Before System.out.println("Before:"); references.forEach(r -> { System.out.println("Reference: " + r); System.out.println("Object: " + r.get()); }); // GC object = null; System.gc(); System.gc(); System.gc(); // After System.out.println("After:"); references.forEach(r -> { System.out.println("Reference: " + r); System.out.println("Object: " + r.get()); }); }
Exit:
Before: Reference: java.lang.ref.WeakReference@238e0d81 Object: java.lang.Object@31221be2 After: Reference: java.lang.ref.WeakReference@238e0d81 Object: null
Your best approach is probably to simply ignore entries in which get() returns null as soon as you "popped" them.
Note: my first test was with the -object string, which never received GC: ed. This is because strings in Java are interned (see String.intern() ), which means that there is a hidden cache of static strings that are reused. A line will never be GC: ed unless this pool of strings is full (or something along this line ...). I think that strings are the only Java object with this βspecialβ characteristic, but I would recommend always using custom objects in WeakReference to make sure it gets GC: ed correctly.
Erk
source share