Understanding the Java String.intern() Memory Model
Calling string.intern() in Java first looks up the corresponding string in the string constant pool; if it doesn't exist, the string is created in the pool and then returned.
- Ryan
- 2 min read

As you know, calling string.intern() in Java first looks up the corresponding string in the string constant pool; if the string does not exist, it is created in the pool and then returned.
The string constant pool is a fixed-size HashMap whose default bucket count is 1009; starting from Java 7u40, this default was increased to 60013. In Java 6, the string constant pool was located in the Perm space, and starting from Java 7 it was moved to the Heap space. Below, we use a test program to look at the memory allocation of the string constant pool under the two different versions, Java 6 and Java 7.
Test program
public class StringPoolTest {
public void testStringPoolWithLongString(){
long i=0;
while(true){
String longString = "This is a very long string, very very long string to test the gc behavior of the string constant pool"+i;
longString.intern();
i++;
}
}
public static void main(String[] args){
StringPoolTest stringPoolTest = new StringPoolTest();
stringPoolTest.testStringPoolWithLongString();
}
}
The test program is simple: an infinite loop that generates a unique string by incrementing the variable i, then starts via the main function.
Java 6
We run this program with JDK 1.6.0_29 and monitor it with Java VisualVM. We can see that the Perm area keeps triggering GC, from which we conclude that although the string constant pool is placed in the Perm space, when the Perm space is nearly full, the JVM will reclaim useless strings in the string constant pool.

Java 7
Next, we switch to JDK 1.7.0_67 and rerun the program. We can see that the Perm area memory allocation curve is very smooth, with no memory allocation activity.

But in the Heap space, new objects are constantly created and GC is triggered repeatedly.

Conclusion
Because the Perm area is limited in size — usually only tens of MB — it is not recommended to use String.intern() extensively under Java 6. The performance tests in this article show that heavy use of intern() under Java 6 leads to a significant performance degradation and can even cause OOM errors. But starting from Java 7, the string constant pool was moved to the Heap space, whose size is limited only by the machine’s actual memory. Therefore, using String.intern() under Java 7 can more effectively reduce the memory footprint of duplicate String objects.
- Tags:
- Java
- JVM
- Memory Model
Frequently Asked Questions
What does String.intern() do?
String.intern() looks up the string in the string constant pool. If an equal string already exists, it returns the pooled reference. If not, it adds the string to the pool and returns the reference.Should I use String.intern() in production?
intern() is safer. However, excessive use can still cause performance issues due to pool contention. For most use cases, a HashMap or ConcurrentHashMap is a better choice for string deduplication.Why does Java 6 behave differently from Java 7 for intern()?
intern() usage could easily cause OutOfMemoryError. Starting from Java 7, the pool was moved to the Heap, which is much larger and only bounded by physical memory.