I just announced the new Spring 5 modules in REST With Spring:

1. Overview

In this quick article, we’ll explore the Java String Pool — the special memory region where Strings are stored by the JVM.

2. String Interning

Thanks to the immutability of Strings in Java, the JVM can optimize the amount of memory allocated for them by storing only one copy of each literal String in the pool. This process is called interning.

When we create a String variable and assign a value to it, the JVM searches the pool for a String of equal value.

If found, the Java compiler will simply return a reference to its memory address, without allocating additional memory.

If not found, it’ll be added to the pool (interned) and its reference will be returned.

5. Garbage Collection

Before Java 7, the JVM placed the Java String Pool in the PermGen space, which has a fixed size — it can’t be expanded at runtime and is not eligible for garbage collection.

The risk of interning Strings in the PermGen (instead of the Heap) is that we can get an OutOfMemory error from the JVM if we intern too many Strings.

From Java 7 onwards, the Java String Pool is stored in the Heap space, which is garbage collected by the JVM. The advantage of this approach is the reduced risk of OutOfMemory error because unreferenced Strings will be removed from the pool, thereby releasing memory.

6. Performance and Optimizations

In Java 6, the only optimization we can perform is increasing the PermGen space during the program invocation with the MaxPermSize JVM option:

-XX:MaxPermSize=1G

In Java 7, we have more detailed options to examine and expand/reduce the pool size. Let’s see the two options for viewing the pool size:

-XX:+PrintFlagsFinal

-XX:+PrintStringTableStatistics

The default pool size is 1009. If we want to increase the pool size, we can use the StringTableSize JVM option:

-XX:StringTableSize=4901

Note that increasing the pool size will consume more memory but has the advantage of reducing the time required to insert the Strings into the table.

7. A Note About Java 9

Until Java 8, Strings were internally represented as an array of characters – char[], encoded in UTF-16, so that every character uses two bytes of memory.

With Java 9 a new representation is provided, called Compact Strings. This new format will choose the appropriate encoding between char[] and byte[] depending on the stored content.

Since the new String representation will use the UTF-16 encoding only when necessary, the amount of heap memory will be significantly lower, which in turn causes less Garbage Collector overhead on the JVM.

8. Conclusion

In this guide, we showed how the JVM and the Java compiler optimize memory allocations for String objects via the Java String Pool.