How does string interning work in Java 7+? [duplicate]
Asked Answered
L

2

16

So, I realize the questions I'm about to ask relate to a topic that has been beaten to death time and time again, however, even after reading all of the answers and documentation I could find, I'm still kind of confused about string interning. Perhaps it's due to my lack of understanding for the JVM; perhaps it's due to the changes introduced in Java 7 depreciating many of the aforementioned answers and documentation. Either way, I'm stuck, and I'm hoping someone can help me understand the concept a bit more clearly...

String a = "text";
String b = new String("text");

In the above example, I understand that two String objects will be created. I also understand that there will be only one char array containing the sequence 't', 'e', 'x', and 't' in memory.

However, where in memory are each of the string objects actually stored?

If what I've read I've read correctly: the referent of variable a will be stored in the constant pool whereas the referent of b will be stored in the heap, right?

If that be the case, I'm confused as to how the intern pool maintains interned strings. Does it keep track of the Strings defined in the constant pool and those that have been manually interned (invoked .intern()) from the heap? Does the JVM create the string objects defined in the constant pool and load them into the intern pool? I'm confused as to how it all works...

Again, sorry for asking such confusing/asinine questions, it's just that I'm relatively new to the structure and inner-workings of the JVM and a lot of it has left my head spinning. Thanks!

Lyford answered 30/11, 2014 at 5:14 Comment(2)
i suggest you read all the answers hereClouet
Nothing fundamental has changed with regard to string interning in Java 7 and 8 compared to older versions.Cleopatracleopatre
I
8

There's a thing called String Memory Pool in java, when you declare:

String str1="abc";

It goes to that memory pool and not on the heap. But when you write:

String str2=new String("abc");

It creates a full fledged object on the heap, If you again write:

String str3 = "abc"; 

It won't create any more object on the pool, it will check the pool if this literal already exists it will assign that to it. But writing:

String str4 = new String("abc");

will again create a new object on the heap

Key point is that:

A new object will always be created on the heap as many times as you keep writing:

new String("abc");

But if you keep assigning the Strings directly without using the keyword new, it will just get referenced from the memory pool (or get created if not present in the memory pool)

intern() method finds if the string is present in the memory pool if it is not it adds it to the memory pool and returns a reference to it. so after using this method the String reference of yours is not pointing to any object on the heap, it is pointing to an object in the String Memory Pool (Also, note that the memory pool only contains unique strings).

Irradiance answered 30/11, 2014 at 5:44 Comment(3)
As of jdk 7 & 8, interned String objects are also stored in heap. java-performance.info/string-intern-in-java-6-7-8Scrivener
What about new String("test").intern() place the object if not already existing? And what if 1. the literal is already in pool, or 2. is already in heap ?Burkhart
@Burkhart check the java api docs for intern(), it's purpose is clearly specified.Irradiance
J
6

When you say new String() you get a new Object reference so consider

String a = "text";
String b = new String("text");
System.out.println(a == b);
b = b.intern();
System.out.println(a == b);

Then first a == b will display false because they are different references. If we intern() b by saying b = b.intern() we can then test again and get true. I hope that helps. The above code has worked the same way in Java since version 1.0 (and it still works this way in Java 8 today).

Justinjustina answered 30/11, 2014 at 5:17 Comment(9)
Thanks for the quick response, Elliott. I understand that both of the above conditions yield true. I guess to be more exact, what confuses me is the following: do string values that are specified in the constant pool (which I've managed to read through using the command "javap -c -verbose ClassName.class" in cmd) become instantiated + loaded into the intern pool which is, as of Java 7, found on the heap? Is the constant pool an actual entity during runtime? (Sorry if my question is confusing, if clarification is needed, let me know)Lyford
@KyleMart The first yields false. Try it. I'm trying to explain how the intern() pool works.Justinjustina
My bad. Lol. I truly meant to say that the former of the 2 conditions would yield false. Totally derped when writing my last comment. The reason that the 1st condition equals false is because var a references a string in the intern pool while var b references a string on the heap, right? The thing that confuses me is the relationship between the intern pool and the constant pool.Lyford
@KyleMart consider System.out.println(new Integer(1024) == Integer.valueOf(1024));Justinjustina
That would be false, right? The left operand creates a new integer object while the right's valueOf method creates a new integer object with a val of 1024, caches it, and returns a reference to the cached object.Lyford
@KyleMart Correct. The lesson you are supposed to learn is use .equals() and try and Write Dumb Code. Also, when you use new you create a reference.Justinjustina
Is String#intern native code, or is there a Java implementation in the String class?\Fredrika
The code above prints "false" and "true" on all current implementations, no question. But does the JVM specification guarantee that a String created with new String(…) will never be automatically interned? So, is it guaranteed that a == comparison of any String object whatsoever with a new String(…) will always return false?Yourself
@ujay68: the new operator is guaranteed to create a new object instance having a unique identity. So a reference comparison will always return false as long as it can be precluded that the second object is the one you’ve just created. E.g., if you call intern() on the new string instance or pass it to some unknown code that could, your bets are off…Tasiatasiana

© 2022 - 2024 — McMap. All rights reserved.