Java String Pool: Concept & Advantages

I hope you already heard about string constant pool in Java?

If no, I’ll explain what is it.

The main advantage of the string pool in Java is to reduce memory usage.

When you create a string literal:

String name = "John";

Java checks for the same value in the string pool.

If it’s present, Java takes a reference from the pool and doesn’t create a new object.

Java string pool is following flyweight pattern concept:

A flyweight is an object that minimizes memory usage by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory. Often some parts of the object state can be shared, and it is common practice to hold them in external data structures and pass them to the objects temporarily when they are used.

Keep reading and I’ll explain how string pool works, what is pool size and small reflection cheats that I don’t recommend to use at all ?

How String Pool Works in Java

When you create a new string like this:

String siteName = "explainjava.com"

JVM automatically check is the same value in the string constant pool.

if yes it takes the already existing value.

If no it creates a new string and adds it to the string pool.

To disable this behavior you can create a string using new operator:

String siteName = new String("explainjava.com");

So if you want to add this string to the literal pool you can call native intern() method:

siteName.intern();

Let’s create a simple string comparison example.

As you know if you’re comparing 2 objects using == operator it compares addresses in the memory.

So we will compare 2 strings using == to be 100% sure that it’s the same object or not.

Example:

package com.explainjava;
 
public class StringPoolExperiment {
 
    public static void main(String[] args) {
        String siteName1 = "explainjava.com";
        String siteName2 = "explainjava.com";
        String sitename3 = new String("explainjava.com");
        String sitename4 = new String("explainjava.com").intern();
 
        System.out.println(siteName1 == siteName2); // true
        System.out.println(siteName1 == sitename3); // false
        System.out.println(siteName1 == sitename4); // true
    }
}

It’s 3 test cases:

  1. 2 strings created using quotes should refer to the same object.
  2. If you create a string using new operator it’s not a part of the constant pool, so objects are different.
  3. If you call intern() method Java adds current string to the string pool and 2 string become the same object.

It’s a simple explanation of Java string pool concept and how does it work.

What is Java String Pool Size?

First of all, let’s dive a little bit into a history.

String pool was a part of PermGen until Java 6.

It had a fixed size and could not be expanded at runtime.

Since Java 7 string pool moved to the heap memory.

It’s more flexible and grow up.

String pool is represented as a weak hashmap data structure.

In Java 6 it had a fixed size, according to this bug the default size was 1009.

Since late versions of Java 6 string pool size became configurable via command line argument -XX:StringTableSize=N, N is a size of the hash map.

It’s recommended to use prime numbers for better performance (choosing a hash function).

Hashmap size increased to 60013 in Java 7 u40.

At the same time was added -XX:+PrintStringTableStatistics command line argument for monitoring purposes.

When String Pool is Garbage collected?

It’s part of the heap memory and we can suppose that it can be garbage collected.

Let’s create a small experiment:

package com.explainjava;
 
public class StringPoolExperiment {
 
    public static void main(String[] args) {
        int counter = 0;
        while (true) {
            new String("Subscribe to ExplainJava.com " + counter).intern();
            counter++;
        }
    }
}

I’m just creating strings, adding it to the string pool and using jconsole to monitor what’s going on with heap memory.

An experiment performed on JDK 1.8.0_131 with CMS garbage collector.

According to monitoring results, we can be 100% that string pool values can be garbage collected.

Reflection + String Pool Cheats

Don’t do it the real projects.

It’s some kind of joke, nothing else.

The idea is to change an array of chars inside of the string that is a part of string pool using reflection.

Let’s take a look at “magic” code:

package com.explainjava;
 
import java.lang.reflect.Field;
 
public class StringPool {
 
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        // add "Hello" to pool
        String hello = "Hello";
 
        // Change value of "Hello" string to "Buy Buy"
        Field value = hello.getClass().getDeclaredField("value");
        value.setAccessible(true);
        value.set(hello, "Buy buy".toCharArray());
 
        // Print "Hello" to console
        System.out.println("Hello");
    }
}

What do you think is an output of System.out.println("Hello");?

Yes, the output is Buy buy!

Looks like magic if you have no clue what is string pool and reflection ?

This example is working on Java 8 and should be changed a little bit to make it work on Java 9.

Do you have any question?

Please, ask.

Leave a Comment