Puneet
Puneet

Reputation: 21

String pool - do String always exist in constant pool?

When string is created by using literal, it gets stored in pool. But when new operator is used to create String object, it stores the object in Heap.

But is the object in heap just a pointer to literal stored in pool or is it a simple String object stored in heap which is eligible for GC?

Upvotes: 1

Views: 1454

Answers (2)

chrycon
chrycon

Reputation: 11

It is a String object stored in the heap eligible for GC. I am using Amazon Corretto 17.

I was finding confusing explanations, so I decided to investigate with code, by running a test to compare the String object creation time in each case:

startTime = System.nanoTime();
String a = "a";
endTime = System.nanoTime();
System.out.println(endTime - startTime);

startTime = System.nanoTime();
String b = new String("b");
endTime = System.nanoTime();
System.out.println(endTime - startTime);

Running the above 10 times on my machine(in independent runs of the JVM), the creation of String "a" takes 2100-4900ns and the creation of String "b" takes 4900-15500ns, so the creation of b must do something significantly more expensive than the creation of a.

Then I compared the references of String objects with the same set of characters using the String.intern() method, which returns a reference to the String object in the string pool.

String c = "hello";
String d = new String("hello");
System.out.println(c==d); // false
System.out.println(c==c.intern()); // true
System.out.println(d==d.intern()); // false
System.out.println((c.intern()==d.intern())); // true

With these, we can deduce that c and d point on different objects, c being a String object in the string pool (which from Java8 is stored in non-heap memory) and d being a String object in the heap. Regarding GC, I believe the string pool is garbage collected only when the non-heap memory where it resides reaches a limit. That memory seems to be called Metaspace and replaces PermGen.

Upvotes: 0

Stephen C
Stephen C

Reputation: 718758

Terminology:

  • The Constant Pool is an area in (each) .class file that contains various constants, including strings. No runtime objects exist in the constant pool. It is a region of a file.

  • The String Pool is a runtime data structure used by the JVM to manage certain kinds of strings. (Specifically, String objects that correspond to literals, and String objects added to the pool by String::intern().)

Your question is actually talking about the String Pool, not the Constant Pool.


To answer your questions:

String pool - do String always exist in constant pool?

No. A string object created using new String() doesn't exist in either the string pool or the constant pool.

When string is created by using literal, it gets stored in pool.

The string (which is represented in the constant pool of a classfile being loaded) is created as a String object and added to the string pool. (These steps happen before or as the literal is first used by Java code, and the precise details vary depending on the JVM implementation.)

But when new operator is used to create String object, it stores the object in Heap.

Yes. But the string pool is also part of the Heap. Like I said, it is a data structure, not a region of storage.

(In the old days, the string pool lived in a special heap called the PermGen heap. But PermGen was replaced with something else (MetaSpace), and the string pool doesn't use either ... anymore.

But is the object in heap just a pointer to literal stored in pool or is it a simple String object stored in heap which is eligible for GC?

This is really confused.

All strings are represented as String objects in the (a) heap. That includes strings in the string pool. Even when the string pool was in PermGen.

All String objects that are unreachable are eligible for garbage collection. Even for strings in the string pool. Even for String objects that represent string literals.

But ... wait ... so can string literals be garbage collected?

Yes!! If a String object that represents a string literal becomes unreachable at runtime it is eligible for garbage collection, just like any other String object.

A string literal can become unreachable if the code object(s) that use the literal become unreachable. It can happen, when a classloader becomes unreachable, and class unloading occurs.

And yes, PermGen was garbage collected. At least since JDK 1.2. (IIRC Java 1.0 and maybe 1.1 didn't implement GC for the PermGen heap. But that was fixed a long time ago.)

Upvotes: 10

Related Questions