I am trying to use WeakHashMap as a concurrent Set of weak references.
this.subscribers =
Collections.synchronizedSet(
Collections.newSetFromMap(
new WeakHashMap <>()
)
);
When an element goes to garbage-collection, my set continues to report it as a part of the collection. So it seems the map is ever-growing.
The documentation says:
When a key has been discarded its entry is effectively removed from the map,…
But that does not seem to be the case in practice.
Is there ever a point at which the WeakHashMap clears out the detritus?
Yes, keys cleared after garbage is actually collected
Yes,
WeakHashMapdoes clean out the detritus. The keys that have gone to garbage collection are no longer reported in the size. But you must wait for garbage-collection to actually take place.Seems likely that you were incorrect about your objects going to garbage-collection. Perhaps your objects became candidates for garbage-collection, but have not yet been collected. Try invoking the garbage-collector and waiting a moment for it to complete. But remember, the call to
System.gc()is only a suggestion to the JVM and may be ignored depending on your JVM implementation and current runtime scenario.Here is a complete example app. Notice that the
Setreports a decrease insizewhether callingSet::removeor letting the object go out of scope.See this code run live at IdeOne.com.
In my case, using Java 10.0.2 version of OpenJDK-based Zulu JVM from Azul Systems, the garbage collector does seem to be activating upon my request. If I comment out the delay for a second, or the
System.gccall, then the last size reported remains3rather than the expected2.You can even see this behavior when running this code live at IdeOne.com. Notice how the last item below is
3but above is2.