String
is a special class in Java. It has very high importance in concurrent
programming as well because String is immutable.
Since, String is immutable, so they should be reused. In order to reuse String
objects JVM maintains a special pool called “String literal pool” or “String constant pool” to store references
of String Objects.
of String Objects.
There are slight differences in various methods of creating
String objects.
1. Creating String Directly [Using String
Literals]:
String str = “hello”;
All the string literals are created and their references are placed in the pool while JVM loads the class. So, the literal(String Object) "hello" will be created in the heap and have a reference in the pool(at the class load time itself) before execution of the following statement
String str = “hello”;.
Hence, whenever our code tries to create a String literal, JVM checks the String Literal Pool and since the string already exists in the pool, a reference to the pooled instance is returned back to the caller.
So, String literals used in Java code always refers to the pooled object of String pool.
JVM keeps at most one object of any String in the literal pool.
String str = “hello”;.
Hence, whenever our code tries to create a String literal, JVM checks the String Literal Pool and since the string already exists in the pool, a reference to the pooled instance is returned back to the caller.
So, String literals used in Java code always refers to the pooled object of String pool.
JVM keeps at most one object of any String in the literal pool.
2. Creating String Using Constructor:
String str = new String(“hello”);
In this case since we are creating String object using “new” keyword, String object will be created in heap memory and this is separate from the String Literal Pool. So, it may happen that String Literal Pool might have the equal String object available but using “new” we will always be able to create different String object with same content.
java.lang.String.intern():
It is String literals that get automatically interned/added to the String pool. String objects created with the “new” operator do not refer to objects in the String Literal Pool but can be made to by using String’s intern() method. The String.intern() returns an interned String, that is, one that has an entry in the global String Literal Pool. Using intern(), if the String is not already in the global String Literal Pool, then it will be added.
You can inspect constant pool of a class by running javap -verbose for that class.
java.lang.String.intern():
It is String literals that get automatically interned/added to the String pool. String objects created with the “new” operator do not refer to objects in the String Literal Pool but can be made to by using String’s intern() method. The String.intern() returns an interned String, that is, one that has an entry in the global String Literal Pool. Using intern(), if the String is not already in the global String Literal Pool, then it will be added.
You can inspect constant pool of a class by running javap -verbose for that class.
e.g.: Following code prints “Hello!” (String literal) on
console[Compiled with Java 1.6].
package blog.techcypher.stringpool;
/**
*
* @author abhishek
*
*/
public class StringLiteral {
/**
* main method
*
* @param args
*/
public static void main(String[] args) {
System.out.println("Hello!");
}
}
By inspecting the byte code you can easily see that String Literal “Hello!” resides in the Constant Pool.
Compiled from "StringLiteral.java"
public class blog.techcypher.stringpool.StringLiteral extends java.lang.Object
SourceFile: "StringLiteral.java"
minor version: 0
major version: 50
Constant pool:
const #1 = class #2; // blog/techcypher/stringpool/StringLiteral
const #2 = Asciz blog/techcypher/stringpool/StringLiteral;
const #3 = class #4; // java/lang/Object
const #4 = Asciz java/lang/Object;
const #5 = Asciz <init>;
const #6 = Asciz ()V;
const #7 = Asciz Code;
const #8 = Method #3.#9; // java/lang/Object."<init>":()V
const #9 = NameAndType #5:#6;// "<init>":()V
const #10 = Asciz LineNumberTable;
const #11 = Asciz LocalVariableTable;
const #12 = Asciz this;
const #13 = Asciz Lblog/techcypher/stringpool/StringLiteral;;
const #14 = Asciz main;
const #15 = Asciz ([Ljava/lang/String;)V;
const #16 = Field #17.#19; // java/lang/System.out:Ljava/io/PrintStream;
const #17 = class #18; // java/lang/System
const #18 = Asciz java/lang/System;
const #19 = NameAndType #20:#21;// out:Ljava/io/PrintStream;
const #20 = Asciz out;
const #21 = Asciz Ljava/io/PrintStream;;
const #22 = String #23; // Hello!
const #23 = Asciz Hello!;
const #24 = Method #25.#27; // java/io/PrintStream.println:(Ljava/lang/String;)V
const #25 = class #26; // java/io/PrintStream
const #26 = Asciz java/io/PrintStream;
const #27 = NameAndType #28:#29;// println:(Ljava/lang/String;)V
const #28 = Asciz println;
const #29 = Asciz (Ljava/lang/String;)V;
const #30 = Asciz args;
const #31 = Asciz [Ljava/lang/String;;
const #32 = Asciz SourceFile;
const #33 = Asciz StringLiteral.java;
{
public blog.techcypher.stringpool.StringLiteral();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 8: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lblog/techcypher/stringpool/StringLiteral;
public static void main(java.lang.String[]);
Code:
Stack=2, Locals=1, Args_size=1
0: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #22; //String Hello!
5: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 16: 0
line 17: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
}
Some Key Points about String Literal Pool:
- An object is eligible for garbage collection if it has no live references from active parts of the JVM/application. In the case of String literals, they always have a reference to them from the String Literal Pool and therefore, they are not eligible for garbage collection until the class and its class-loader is unloaded.
- All the string literals are created and their references are placed in the pool while JVM loads the class.
- 05:06
- 5 Comments