Garbage collection on intern'd strings, String

2019-01-08 01:56发布

问题:

After exploring java's string internals I've grown confused on what is referred to as the "perm space." My understanding initially of it was that it held String literals as well as class meta data as explained in this question.

I've also read about the String.intern() method and that it places Strings into the String Pool returning a reference to unique instance of it. It is my understanding that this is the same string pool holding String literals that exists in the JVM's perm-space. It didn't seem possible to me that the "perm-space" could be modifiable, (it is permanent after all, yes?). But Then I found this question where the top voted comment by EJP on the accepted answer explains that

Intern'd strings have been GC-able for quite some years now.

Implying that the GC runs on the perm-space which doesn't seem very permanent. How does this reconcile? Does the GC check everything in the perm-space? Does the GC check everything in the string pool including string literals from the source? Is there a second string pool for intern'd strings? Does the GC know only to look over intern'd strings when collecting? Or is this comment mistaken and intern'ing a string prevents it from ever being GC'd (which I hope is not the case)?

回答1:

String literals are interned. As of Java 7, the HotSpot JVM puts interned Strings in the heap, not permgen.

Prior to java 7, hotspot put interned Strings in permgen. However, interned Strings in permgen were garbage collected. Apparently, Class objects in permgen are also collectable, so everything in permgen is collectable, though permgen collection might not be enabled by default in some old JVMs.

String literals, being interned, would be a reference held by the declaring Class object to the String object in the intern pool. So the interned literal String would only be collected if the Class object that referred to it were also collected.