1

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?

2

2 Answers 2

10

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.)

Sign up to request clarification or add additional context in comments.

2 Comments

creating a String using literal doesn't neccessarily means that it is a constant. Isn't it ? So, why should it exist in constant pool ?
Please read the start of the my answer. The constant pool refers to things in the class file that the JVM specifications calls constants. This is nothing to do with final ... though there is a relationship with constant expressions. A string literal is a constant expression.
0

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.

6 Comments

BTW there is no 'creation of String "a"' in String a = "a";
@user85421 Why do you say that?
quoting from your post "Running the above 10 times ... the creation of String "a" takes ..." and the code is measuring String a = "a"; - but the literal "a" is eventually created before, and only once
@user85421 What I meant was that I ran the above in 10 different runs. Since the JVM is restarted each time, the strings are added to the string pool every time. I will rephrase my answer to clarify, thank you.
you restartet the JVM for every measurement? I would recommend reading the answer to How do I write a correct micro-benchmark in Java? (BTW there are a couple of strings already interned when main is called, eventually depending on JVM implementation, in my system, "java" is one of these, for example)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.