• Post Reply Bookmark Topic Watch Topic
  • New Topic

String object vs. string pool  RSS feed

 
henry leu
Greenhorn
Posts: 17
2
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I'm studying Java 8 OCA 1Z0-808 using the book by Jeanne Boyarsky and Scott Selikoff.

In chapter 3 page 111, I am confused about whether it is string pool or String object. See the following code.
The book says it will create 27 String objects and these 27 String objects will be immediately available for garbage collection.
So my guess is, "" is a String object? Line 10. It looks like a string literal to me and should be in string pool?
And also any String concatenation is String object? Line 12
Another question is that I know String object can be garbage collected. What about literals in the string pool? Do they get garbage collected?



Thanks,
Henry
 
praveen kumaar
Ranch Hand
Posts: 461
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Henry,
I don't have that book but may be this could help.
whenever you see a String literal or a String object(created with new keyword) then note it that they both are Object present or created on the heap.
you should have a question that what is a difference b/w the 2 ?
JVM maintains a String Pool(internally) where it contains an implicit reference to the String object referred through a String literal in your code.In other words when your class file is loaded in the JVM it checks for any string literal in there if it founds a one then it creates an object on heap and implicitly create a reference to that object and put that reference in the pool(you cannot have any control over this reference).

Another question may be what did we gain from it ?
this pool provides a String Interning.means if any where in your program if the same string is needed for use(i mean if the same literal is used again in your code) then jvm will use the same copy.

where as the whenever you will create a String object using new keyword then it will always create a new copy on the heap.
Henry wrote:So my guess is, "" is a String object? Line 10. It looks like a string literal to me and should be in string pool?

Yes it is a String Object though it is created internally.and yes it is a string literal and jvm has an implicit reference to this object in a pool.

Henry wrote:And also any String concatenation is String object? Line 12

Yes String concatenation is an Object too but again it is created internally(if the pool has already reference to that object then in that case it will not create the new one as per string interning).

Henry wrote:Another question is that I know String object can be garbage collected. What about literals in the string pool? Do they get garbage collected?

As i have told you that String pool does not contain the object but a implicit reference to that literals so due to these active references they are not eligible for garbage collection(never).

Hope it helps!

Kind Regards,
Praveen.
 
praveen kumaar
Ranch Hand
Posts: 461
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can also go throughJava® Language Specification/String Literal.

I have some edit for my last post:
I wrote:...so due to these active references they are not eligible for garbage collection(never).

First of all my apologies for,may be,some wrong info.
I have gone through this articleCan interned strings be garbage collected.
This article says yes possible!

I will need a view on it by some members.

Kind Regards,
Praveen.
 
Stephan van Hulst
Saloon Keeper
Posts: 7969
143
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
praveen kumaar wrote:Yes String concatenation is an Object too but again it is created internally(if the pool has already reference to that object then in that case it will not create the new one as per string interning).

This is not correct. Strings are only interned when you use a String literal, or when you call String.intern() or any other method that calls String.intern().

The + operator returns a new String object, but it is not interned.

In this particular example, the initial value of alpha is interned, because it's initialized with a String literal.

Every time current gets appended to alpha, a new String object is created, but that new object will not be interned. Because alpha is overwritten each time, the previous value will become eligible for garbage collection, except "" because it's in the string pool, and "abcdefghijklmnopqrstuvwxyz", because it's not overwritten and alpha still has a reference to it. That last string will become eligible for garbage collection when the method body finishes executing.
 
Roel De Nijs
Sheriff
Posts: 11338
177
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
henry leu wrote:The book says it will create 27 String objects and these 27 String objects will be immediately available for garbage collection.
So my guess is, "" is a String object? Line 10. It looks like a string literal to me and should be in string pool?
And also any String concatenation is String object? Line 12
Another question is that I know String object can be garbage collected. What about literals in the string pool? Do they get garbage collected?

This topic has a great explanation (with additional code snippets) about the same code snippet. Definitely worth reading!
 
henry leu
Greenhorn
Posts: 17
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for all the answers!

But I still have one question.

After line 2, we should have 2 Strings objects in the heap, right? "java" and "c++". What about after line 3? Do we get 2 String objects or 3 String objects on the heap?

For line 3, s2.intern() will check the string pool table and see if "c++" exists. This case it doesn't exist. So "c++" will be added to the string pool. Now, will Java create another new String object on the heap, another "c++" object?

What reference will s3 receive?

 
Stephan van Hulst
Saloon Keeper
Posts: 7969
143
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
After line 2, there are two strings in the pool: "java" and "c++", because both have been created using a string literal. There also exists a third string object with the same value as "c++", but it's a different object that has not been interned.

At line 3, the object referenced by s2 has its value compared to that of the strings in the string pool. Since it equals "c++" which is already in the string pool, the intern() method won't save the object to the string pool, and it will return a reference to the original object that was created by using the string literal "c++".

You can test this by saving the reference to the original object, getting the interned version of the new object, and comparing them by reference:
 
henry leu
Greenhorn
Posts: 17
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
henry leu wrote:Thanks for all the answers!

But I still have one question.

After line 2, we should have 2 Strings objects in the heap, right? "java" and "c++". What about after line 3? Do we get 2 String objects or 3 String objects on the heap?

For line 3, s2.intern() will check the string pool table and see if "c++" exists. This case it doesn't exist. So "c++" will be added to the string pool. Now, will Java create another new String object on the heap, another "c++" object?

What reference will s3 receive?



See the attached picture for my understanding of the code above. Please verify if this is correct.

Thanks!
 
henry leu
Greenhorn
Posts: 17
2
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
henry leu wrote:Thanks for all the answers!

But I still have one question.

After line 2, we should have 2 Strings objects in the heap, right? "java" and "c++". What about after line 3? Do we get 2 String objects or 3 String objects on the heap?

For line 3, s2.intern() will check the string pool table and see if "c++" exists. This case it doesn't exist. So "c++" will be added to the string pool. Now, will Java create another new String object on the heap, another "c++" object?

What reference will s3 receive?

IMG_20170122_185406.jpg
[Thumbnail for IMG_20170122_185406.jpg]
 
Stephan van Hulst
Saloon Keeper
Posts: 7969
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your drawing is correct.
 
Roel De Nijs
Sheriff
Posts: 11338
177
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I like to add two things.

First of all, this article has an excellent explanation about String literals and the String Literal Pool. Definitely worth reading!

Secondly, here's another topic about the intern() method, but please keep in mind that  the intern() method is not on the OCAJP exam.
 
Roel De Nijs
Sheriff
Posts: 11338
177
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
henry leu wrote:See the attached picture for my understanding of the code above. Please verify if this is correct.

That definitely deserves a cow!
Content minimized. Click to view
 
praveen kumaar
Ranch Hand
Posts: 461
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan wrote:This is not correct. Strings are only interned when you use a String literal, or when you call String.intern() or any other method that calls String.intern().

The + operator returns a new String object, but it is not interned...
Stephan,Thanks for mentioning it but saying that "+" will not intern the string is not
true for the case below where i had use it to concatenate 2 String literal.
 
Stephan van Hulst
Saloon Keeper
Posts: 7969
143
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is probably because the compiler is smart enough to rewrite "Step"+"han" to "Stephan", which gets added to the String pool when the application starts.

Try this instead:
 
praveen kumaar
Ranch Hand
Posts: 461
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay I got it Stephan,Thanks.
But as far as the Garbage collection of the Interned String is concerned i found that Interned Strings can be Garbage CollectableThese are not my words actually i found it here.
I will request both of you,@Roel and @Stephan,to look in this link and please let me know if it's correct.

Kind Regards,
Praveen.
 
Stephan van Hulst
Saloon Keeper
Posts: 7969
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I suppose a valid implementation of the string pool could use soft references to strings, meaning that interned strings get garbage collected when there are no strong references to them anymore.

I'm not sure if this actually happens though. I imagine that for most applications, only literals are interned and if the developer crashes their machine by interning too many strings, so be it.
 
Roel De Nijs
Sheriff
Posts: 11338
177
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
praveen kumaar wrote:But as far as the Garbage collection of the Interned String is concerned i found that Interned Strings can be Garbage Collectable

Honestly I don't really care! Not for the OCAJP exam (because the intern() method is not on the exam), nor for my real life development (I have been a Java developer since 2004 and never had to use the intern() method).

It would be strange/weird/inconsistent if String literals behave differently regarding GC than all other objects in Java. So it makes sense that all strings in the JVM string pool are eligible for GC if there are no references to them from your application. Here is another article confirming this behavior.
 
praveen kumaar
Ranch Hand
Posts: 461
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan wrote:That is probably because the compiler is smart enough to rewrite "Step"+"han" to "Stephan", which gets added to the String pool when the application starts.
Yes you are completely correct.next time you can just remove the the word "probably" from your quote.i have try disassembling this code:
Here is the Disassembled code:

You can easily view the difference:using "+" on the 2 string references make use of a StringBuilder object and its append method and in contrast using "+" on 2 String literals directly is easily interpreted as the resultant string constant(so is interned).

Kind Regards,
Praveen.
 
Stephan van Hulst
Saloon Keeper
Posts: 7969
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm actually really surprised that the compiler doesn't inline the two String literals (and then reduces it further by eliminating the concatenation), because step and han are effectively final. That's the reason I used overridable method calls instead of variables.

Oh well. Nice job, have a cow!
 
Roel De Nijs
Sheriff
Posts: 11338
177
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:I'm actually really surprised that the compiler doesn't inline the two String literals (and then reduces it further by eliminating the concatenation), because step and han are effectively final.

That's probably because in the class Test (which praveen used to decompile) the reference variables step and han are not declared final. This code snippetresults in the following byte codeNo use of StringBuilders here. That compiler is really one smart cookie!

Disclaimer: this is waaaaaaaaaaaay beyond the scope of the OCAJP (and even OCPJP) certification exam.
 
praveen kumaar
Ranch Hand
Posts: 461
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel,in my case it make use of a StringBuilder is it because compiler cannot be sure that variable step and han will always point to the literal step and han resectively and in your case the final modifier has make the variable compile time constants(so the compiler will put the respective literal accordingly with step and han wherever these variables are used).
but when i tried to decompile it,i got:

In my case it doesn't even loads the String literal "step" and "han".can you explain,why?
Another thing is here again both stephan_1 and stephan_2 are interned.

Anyway,i am not preparing for OCAJP or any exams.i just love to learn new things and add it to my knowledge(i don't have any instructor or guide so i have to learn by myself,that's why i am asking these much things).Hope these things will not annoy you.

Kind regards,
Praveen.
 
Femy Anish
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I'm also  preparing for Java 8 OCA 1Z0-808 using the book by Jeanne Boyarsky and Scott Selikoff.

I too have a doubt regarding String literal and String object.My simple question is if we type String str = "abc". Do it create only a literal in the String pool or will it create a String object in the heap.
 
praveen kumaar
Ranch Hand
Posts: 461
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Femy,
Welcome to CodeRanch!
simply explore through all the replies in this post and their were links given by @Roel go through them,you will get your doubts clear.even then if you have any doubts unclear,create a new topic and inside it tell us about your query we will guide to sort your problem there.

kind regards,
praveen.
 
Femy Anish
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the Reply.

I will go through the previous replies and link and will get back in case of doubt.

Regards,
Femy
Content minimized. Click to view
 
Roel De Nijs
Sheriff
Posts: 11338
177
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
praveen kumaar wrote:In my case it doesn't even loads the String literal "step" and "han".can you explain,why?

My guess would be "compiler optimization". The compiler sees you are trying to concatenate two Strings which are also compile-time constants and performs these String concatenations at compile-time (and save a few CPU cycles at run-time).
 
Umberto D'Ovidio
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Femy Anish wrote:Hi,

I'm also  preparing for Java 8 OCA 1Z0-808 using the book by Jeanne Boyarsky and Scott Selikoff.

I too have a doubt regarding String literal and String object.My simple question is if we type String str = "abc". Do it create only a literal in the String pool or will it create a String object in the heap.

It creates also an object in the heap, which is referenced by the literal in the string pool
 
Roel De Nijs
Sheriff
Posts: 11338
177
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Femy Anish wrote:I too have a doubt regarding String literal and String object.My simple question is if we type String str = "abc". Do it create only a literal in the String pool or will it create a String object in the heap.

The String object "abc" is created on the heap and a reference (address) to this object is stored in the String Literal Pool, so only one object will be created.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!