Thursday, May 11, 2023

Difference in String pool between Java 6 and 7? Answer

String pool in Java is a pool of String literals and interned Strings in JVM for efficient use of String objects. Since String is immutable in Java, it makes sense to cache and shares them in JVM. The String pool has gone through an important change in Java 7 release when it was relocated from PermGen space to heap space. Till Java 1.6, interned String and literals are stored in the PermGen space of JVM memory, which was a fixed size area for storing class metadata. The biggest issue of having a String pool in PermGen is the small and fixed size of PermGen space.

In some JVM it ranges from 32M to 96M, which is quite small for a large program. Since String is extensively used in both small and large Java applications, Java designers thought the String pool is the best way to optimize the use of String objects in Java.

Btw, you can also change the size of PermGen space using JVM parameters -XX+PermGenSize, it is still fixed. Such limitation requires very restricted use of String.intern() method, you would better not using String.intern() method in a loop or at a large scale to avoid java.lang.OutOfMemoryError : PermGen space.

By relocating the String pool to heap space, you gain the benefit of large memory space. String pools can grow and shrink much more smoothly than they were in PermGen space. Since String literals and interned String are also garbage collected, the size of the pool will grow and shrink depending upon the state of your program.




String pool changes in Java 7

The JDK 7 introduces many changes e.g. String in the switch case, try-with-resources, better exception handling, and new File API (see the full list here), the change which mostly gone unnoticed but has a significant impact was the change made to String class and the String pool itself.

The default size of the String pool has increased on  Java 7 update 40 release. The String pool is implemented using a HashMap in Java and the default size of the table in Java 6 was 1009, which was further increased to 60013 in Java 7. See Java Performance The Definitive Guide by Scott Oaks to learn more about Java 7 changes that affect the performance of  Java applications.

Difference between String pool in Java 6 and 7


You can also customize string pool size using -XX:StringTableSize parameter. If you do provide a custom size for the String pool, consider giving a prime number. Depending upon your Java application, having a String pool of 1 million entries may not be a bad idea. Though default size of String pool, 60013 is also good enough for many Java programs and hence retained in Java 8 as well.

If you are not sure about String pool usage then you can also print string pool statistics using -XX:+PrintStringTableStatistics JVM option. It will print string pool usage data once your program finished execution.

Due to this relocation of String pool from PermGen memory space to heap space, the String.intern() method, which is used to intern a String object and store it inside string pool for further reuse has now become even more useful. You can intern a large number of String than before. You are only limited by your JVM heap size as far as String pool goes.

In summary here, is the important difference in String pool in Java 6 and 7:
  1. String pool is relocated to Java heap space from PermGen space.
  2. The default size of String pool is increased to 600013 entries from 1009 in Java 6.
  3. The -XX:StringTableSize JVM option is provided to specify the size of the String pool. 
Apart from that String class is also changed e.g. now the char[] is not referenced when you create substring, instead, a new array is created with only necessary data required by the substring method, as shown below:

changes in String pool in Java 7



That's all about the difference between String pool in Java 6 and 7. It is one of the important details which many Java developer doesn't know but it can affect both performance and stability of your Java application. If you are still not running on Java 7, then the first steps are to switch to Java 7 runtime and then try for Java SE 8 upgrade as Java 9 is not very far away :-).

Other Java String articles You may like:
  • Why was the String class made final in Java? (answer)
  • How substring method of String works in Java? (answer)
  • Why char[] is better than String for storing a password in Java? (answer)
  • 10 Things Every Java Programmer should know about String? (answer)
  • How String in switch case works in Java 7? (answer)
  • How to format String in Java? (answer)
  • How to check if String is null or empty in Java? (solution)

5 comments :

Aman said...

Nice Article ! :)

Unknown said...

Informative!
Thanks for the information.

Unknown said...

good article
thanks

Anonymous said...

Good article. one small correction is required. In one paragraph string pool size is mentioned as 60013 and in another paragraph it is mentioned as 600013(extra zero).
I think it must be 60013.

Rajkumar said...

Hi,

I want to have a clarification.

String subject = "Java";

Here new "string instance" will be created in Heap at some reference say 1234 and, the literal("Java") and string object reference(1234) will be stored in string constant pool. Is my understanding correct?

Post a Comment