This is NOT due to the row pool itself.
The real reason is that the ReferenceTest class has an implicit hard link to a String object that represents the literal "I'm here" . This hard link means that the weak link in sr will not be broken by garbage collection 1 .
Actually:
An implicit reference would be necessary even if String objects corresponding to literals were not combined. (They are combined ... JLS effectively requires this ... but I say that links would be required even if they were not. An alternative for Java would be to mint a new String object every time a string literal expression was This would be terrible inefficient !!)
The string pool internally uses the weak link form ... so that unlisted interned strings can be garbage collected. If this is not the case, then each new interned line will be a memory leak.
In any case ... if you carefully build the string without using a string literal, and put it like this:
char[] chars = {'a', 'b', 'c'}; WeakReference r = new WeakReference(new String(chars).intern());
... you should find that the weak link (in the end) is broken. (This may take several GC cycles.)
1 - Theoretically, by causing class unloading and garbage collection, you can get rid of the last available reference to this string literal. However, if this happened in this case, you will pass the point where you can observe the state of the WeakReference object. At least with your sample code. In addition, if you do not load the JVM using a special class loader, I don’t think it would be possible to infer entrypoint class unloading. This is not something that is easy or beneficial to do.
source share