1

When we intern a string, we are making sure that all uses of that string are referring to the same instance.

I would assume that the underlying string object is in the heap.

However, where is the referring variable stored in the memory?

Does it have the same behaviour as static - wherein the reference gets stored in permgen and makes the string instance available for gc only after the classloader(and application) exits?

SimonC
  • 6,590
  • 1
  • 23
  • 40
IUnknown
  • 9,301
  • 15
  • 50
  • 76
  • 1
    Static references do not get stored in the perm gen. – SimonC May 31 '13 at 02:59
  • Not sure what you mean by "referring variable". There is a sort of directory of interned strings, but that's hidden and you don't need to worry about it. Any reference you have to an interned string can have whatever storage class you desire. – Hot Licks May 31 '13 at 02:59
  • 1
    @SimonC - actually, static references can be in permgen, because the static frame that holds them can be a permgen object. (It would certainly *make sense* for the static frame to be in permgen, because its lifetime is tied to the classloader that loaded the class!) It is just the objects that static variables refer to that typically aren't. – Stephen C May 31 '13 at 03:19
  • Thats why I am differentiating between the underlying object instance and the referring variable. – IUnknown May 31 '13 at 03:36
  • @StephenC, that makes sense. I was referring to the memory that the static field pointed to, but your description is much clearer! – SimonC May 31 '13 at 03:55
  • See my Answer for clarification on the "referring variable". – Stephen C May 31 '13 at 05:47
  • What difference does it make where it's stored? The semantic is guaranteed to be preserved regardless of the peculiarities of the current JVM's heap management. – Hot Licks May 31 '13 at 11:11
  • (And you still didn't explain what you mean by "referring variable".) – Hot Licks May 31 '13 at 11:12

2 Answers2

5

Up to JDK 6, Intern'ed strings are stored in the memory pool in a place called the Permanent Generation, which is an area of the JVM that is reserved for non-user objects, like Classes, Methods and other internal JVM objects. The size of this area is limited, and is usually much smaller than the heap.

From JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.

A detailed explanation of this can be found on this answer.

Community
  • 1
  • 1
Bigger
  • 1,807
  • 3
  • 18
  • 28
2

When we intern a string, we are making sure that all uses of that string are referring to the same instance.

Not exactly. When you do this:

    String s2 = s1.intern();

what you are doing is ensuring that s2 refers to a String in the string pool. This does not affect the value in s1, or any other String references or variables. If you want other copies of the string to be interned, you need to do that explicitly ... or assign interned string references to the respective variables.

I would assume that the underlying string object is in the heap.

That is correct. It might be in the "permgen" heap or the regular heap, depending on the version of Java you are using. But it is always "in the heap".

However, where is the referring variable stored in the memory?

The "referring variable" ... i.e. the one that holds the reference that you got from calling intern() ... is no different from any other variable. It can be

  • a local variable or parameter (held in a stack frame),
  • an instance field (held in a regular heap object),
  • a static field (held in a permgen heap object) ... or even
  • a jstring variable or similar in JNI code (held "somewhere else".)

In fact, a typical JVM uses a private hash table to hold the references to interned strings, and it uses the JVM's weak reference mechanism to ensure that interned strings can be garbage collected if nothing else is using them.

Does it have the same behaviour as static - wherein the reference gets stored in permgen and makes the string instance available for gc only after the classloader(and application) exits?

Typically no ... see above.

In most Java platforms, interned Strings can be garbage collected just like other Strings. If the interned Strings are stored in "permgen" space, it may take longer for the object to be garbage collected, because "permgen" is collected infrequently. However the lifetime of an interned String is not tied to the lifetime of a classloader, etc.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216