I encountered some troubles with WeakHashMap.
Consider this sample code:
List list = new ArrayList();
Map
Bit of digging reveals that this is explicitly covered in the JLS, section 12.6.1:
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
(Bolding is my addition.)
http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.6.1
So in essence, the JIT is allowed to remove strong references whenever it wants if it can work out that they'll never be used again - which is exactly what's happening here.
This is a great question though and makes for a great puzzler that can easily show just because an object appears to have a strong reference in scope, doesn't necessarily mean it hasn't been garbage collected. Following on from this it means you explicitly can't guarantee anything about when a finalizer will run, this may even be in the case where it seems like the object is still in scope!
Eg:
List list = new ArrayList();
Object thing = new Object() {
protected void finalize() {
System.out.println("here");
}
};
WeakReference
The above is a simpler example that shows the object gets finalized and GC'd first even though the reference to thing
still exists (here is printed, then bam.)