Like many Java objects, all String
instances are created on the heap, even literals. When the JVM finds a String
literal that has no equivalent reference in the heap, the JVM creates a corresponding String
instance on the heap and it also stores a reference to the newly created String
instance in the String pool. Any other references to the same String
literal are replaced with the previously created String
instance in the heap.
Let's look at the following example:
class Strings
{
public static void main (String[] args)
{
String a = "alpha";
String b = "alpha";
String c = new String("alpha");
//All three strings are equivalent
System.out.println(a.equals(b) && b.equals(c));
//Although only a and b reference the same heap object
System.out.println(a == b);
System.out.println(a != c);
System.out.println(b != c);
}
}
The output of the above is:
true
true
true
true
When we use double quotes to create a String, it first looks for String with same value in the String pool, if found it just returns the reference else it creates a new String in the pool and then returns the reference.
However using new operator, we force String class to create a new String object in heap space. We can use intern() method to put it into the pool or refer to other String object from string pool having same value.
The String pool itself is also created on the heap.
Before Java 7, String
literals were stored in the runtime constant pool in the method area of PermGen
, that had a fixed size.
The String pool also resided in PermGen
.
In 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.