Rapidly getting a strong reference out of the WeakReference, does not prevent the weakly referenced object from being collected.
Here’s the proof:
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
public class WeakReferenceProof {
public static void main(String[] args) {
Object monitor = new ArrayList<String>(64 * 1024);
WeakReference<Object> weak = new WeakReference<Object>(monitor);
monitor = null;
int counter = 0;
do {
Object ref = weak.get();
System.out.println("weak.ref=" + ref);
ref = null;
counter++;
System.out.println("garbage: " + createGarbage());
} while (weak.get() != null);
System.out.println("Done, after " + counter + " iterations");
}
private static int createGarbage() {
// create some varying size garbage
List<byte[]> holder = new ArrayList<>();
for (int i = 0; i < 64; i++) {
holder.add(new byte[i]);
}
// prevent HotSpot from optimizing everything away
int sum = 0;
for (byte[] data : holder) {
sum += data.length;
}
return sum;
}
}
It obviously terminates fairly quickly, within a few seconds. If your statement would be true, it would hold on to the reference indefinitely, making the process run forever.
[quote=“Best_Username_Ever,post:19,topic:40000”]
Well, I’ll even go the extra mile and make a really tight ‘update loop’, creating the ideal conditions for your reported ‘effectively strong reference’:
public static void main(String[] args) {
Object monitor = new ArrayList<String>(64 * 1024);
final WeakReference<Object> weak = new WeakReference<Object>(monitor);
monitor = null;
new Thread(new Runnable() {
@Override
public void run() {
while (weak.get() != null) {
System.out.println("garbage: " + createGarbage());
}
}
}).start();
int counter = 0;
do {
Object ref = weak.get();
System.out.println("weak.ref=" + ref);
counter++;
} while (weak.get() != null);
System.out.println("Done, after " + counter + " iterations");
}
Same deal.