String str1="JAVA";
String str2="JAVA";
String str3=new String("JAVA");
String str4=new String("JAVA").intern();
2 objects will be created. str1 and str2 refer to same object because of String literal pool concept and str3 points to new object because using new operator and str4 points to the same object points by str1 and str2 because intern() method checks into string pool for string having same value.
str1=str2=str3=str4=null;
One object will be eligible for GC. That is the object created through String str3=new String("JAVA"). The first String object is always accessible through reference stored in string literal pool.
Is my explanation correct?
Total Number of String objects created in the process?
Three: The one in the intern pool created via the literal and the two you create via new String.
One object will be eligible for GC.
I count two, and possibly even all three under very special circumstances:
The one you created in this line:
String str3=new String("JAVA");
(since you later set str3 to null).
The one you created temporarily in this line:
String str4=new String("JAVA").intern();
That line creates a new String object, calls intern on it, and then saves a reference to the string from the pool. So in theory, it creates a String object that is immediately available for GC. (The JVM may be smart enough not to do that, but that's the theory.)
Possibly, eventually, under the right conditions, even the string in the intern pool. Contrary to popular belief, strings in the intern pool are available for garbage collection as we can see from the answer to this other question. Just because they're in the permgen (unless you're using Oracle's JVM 7 or later) that doesn't mean they're not GC'd, since the permgen is GC'd too. So the question becomes: When or how is a string literal used in code no longer referenced? I don't know the answer, but I think a reasonable assumption would be: When and if the class using it is unloaded from memory. According to this other answer, that can only happen if both the class and its classloader are unloaded (and may not happen even then). If the class was loaded by the system classloader (the normal case), then presumably it's never unloaded.
So almost certainly just two (#1 and #2 above), but it was fun looking into #3 as well.
Related
String s = new String(“hello”);
Here two objects will be created, one in heap memory and another in the string pool.
So, what is the use of the intern() method? The string "hello" will be available in heap as well as the string pool after above statement execution
First of all. String s = new String(“hello”); creates an unnecessary String and should not be used. Next, calling s = s.intern() will ensure that the "hello" added to SCP will be returned and hence the second string that was created on the heap will be eligible for GC.
intern() adds the string to the SCP if it is not already present. It is usually used when you know that a String is used multiple times but you cannot create it using literal. So instead of creating thousands of Strings with the same value, you (which exist simultaneously), you could use intern and ensure that only one String is put in the SCP and is used in 1000 places (and all other strings with the same value on the heap are eligible for GC)
when exactly the object is created in string constant pool when we use new operator.?
It isn't. There is considerable confusion here.
The object in the string pool is created by the compiler and classloader in response to the use of a string literal, in this case "hello".
The new operator creates a new object, on the heap.
The intern() method returns a reference to an object in the string pool that either was already there or was created by the intern() call.
An object is created in the string constant pool if anything is written in double quotes and if it doesn't already exists in the string constant pool.
As for intern() method it returns the canonical representation of string.
For further understanding seehttp://www.javatpoint.com/java-string-intern
what is the use of the intern() method
intern strings gives the simplicity to compare strings with ==(faster) instead of equals function where non-intern can't use the == operator for equality.
String s = new String(“hello”);
new will assign memory to s in heap instead of internal set of unique strings which is maintained by VM ,also known as SCP.All strings found in class at the time of loading calls, are automatically interned(with strong-reference) which leads to efficient memory use.
Calling intern() on s string literal will add a weak-reference(short-time) of s in SCP and also returned that reference so GC will surely free heap memory consumed by s.
Weak-reference will also be deleted when it is no longer used hence again leads to efficient memory management.
When exactly the object is created in string constant pool
String will be added to SCP temorarly, either with direct double quotes(String s="sytax";) syntax or calling intern().
when we use new operator?
Avoid it as much as you can with strings or never.
If jvm creates string pool for memory optimization, then why it creates new Object each time we create string using new keyword even though it exists in string pool?
... why does Java create new Object each time we create a string using the new keyword even though it exists in string pool?
Because you explicitly told it to! The new operator always creates a new object. JLS 15.9.4 says:
"The value of a class instance creation expression is a reference to the newly created object of the specified class. Every time the expression is evaluated, a fresh object is created."
For the record, it is nearly always a mistake to call new String(String) ... but in obscure cases it might be useful. It is conceivable that you might want a string for which equals returns true and == gives false. Calling new String(String) will give you that.
For older versions of Java, the substring, trim and possibly other String methods would give you a string that shared backing storage with the original. Under certain circumstances, this could result in a memory leak. Calling new String(str.trim()) for example would prevent that memory leak, at the cost of creating a fresh copy of the trimmed string. The String(String) constructor guarantees to allocate a fresh backing array as well as giving you a new String object.
This behavior of substring and trim changed in Java 7.
To give primitive style of declaration and for performance designers introduced String literals.
But when you use new keyword, then you are explicitly creating objects on heap not in constant pool.
When the objects created on heap, there is no way to share that memory with each other and they become completely strangers unlike in constant pool.
To break this barrier between heap and constant pool String interning will help you out.
string interning is a method of storing only one copy of each distinct string value, which must be immutable
Remember that constant pool also a small part of heap with some additional benefits where sharing of memory is available.
When you write
String str = new String("mystring");
then it creates a string object in heap just like other object which you create. The string literal "mystring" is stored in the string constant pool.
From the Javadocs:
A pool of strings, initially empty, is maintained privately by the
class String.
When the intern method is invoked, if the pool already contains a
string equal to this String object as determined by the equals(Object)
method, then the string from the pool is returned. Otherwise, this
String object is added to the pool and a reference to this String
object is returned.
It follows that for any two strings s and t, s.intern() == t.intern()
is true if and only if s.equals(t) is true.
To take advantage of string pooling you need to use String#intern instead of new.
Following object will be stored in String pool :
String s = "hello";
And following object will be stored in Heap (not in string pool):
String s = new String ("hello")
To enforce garbage collection!. If you need some String just one time, then there is no point in keeping it in memory (for almost forever. Which is the case with Strings in constant pool). Strings which are not in the constants pool can be GCed like any other object. So, you should only keep frequently used Strings in the constants pool (by using literals or interning them).
Strings created in the form of String literals (String s = "string";) are stored in string pool, but Strings created by invoking String constructor using new (String s = new String("string");, are not stored in string pool.
I am reading about Garbage collection and i am getting confusing search results when i search for String literal garbage collections.
I need clarification on following points:
If a string is defined as literal at compile time [e.g: String str = "java"] then will it be garbage collected?
If use intern method [e.g: String str = new String("java").intern()] then will it be garbage collected? Also will it be treated differently from String literal in point 1.
Some places it is mentioned that literals will be garbage collected only when String class will be unloaded? Does it make sense because I don't think String class will ever be unloaded.
If a string is defined as literal at compile time [e.g: String str = "java";] then will it be garbage collected?
Probably not. The code objects will contain one or more references to the String objects that represent the literals. So as long as the code objects are reachable, the String objects will be to.
It is possible for code objects to become unreachable, but only if they were dynamically loaded ... and their classloader is destroyed.
If I use the intern method [e.g: String str = new String("java").intern()] then will it be garbage collected?
The object returned by the intern call will be the same object that represents the "java" string literal. (The "java" literal is interned at class loading time. When you then intern the newly constructed String object in your code snippet, it will lookup and return the previously interned "java" string.)
However, interned strings that are not identical with string literals can be garbage collected once they become unreachable. The PermGen space is garbage collected on all recent HotSpot JVMs. (Prior to Java 8 ... which drops PermGen entirely.)
Also will it be treated differently from string literal in point 1.
No ... because it is the same object as the string literal.
And indeed, once you understand what is going on, it is clear that string literals are not treated specially either. It is just an application of the "reachability" rule ...
Some places it is mentioned that literals will be garbage collected only when String class will be unloaded? Does it make sense because I don't think the String class will ever be unloaded.
You are right. It doesn't make sense. The sources that said that are incorrect. (It would be helpful if you posted a URL so that we can read what they are saying for ourselves ...)
Under normal circumstances, string literals and classes are all allocated into the JVM's permanent generation ("PermGen"), and usually won't ever be collected. Strings that are interned (e.g. mystring.intern()) are stored in a memory pool owned by the String class in permgen, and it was once the case that aggressive interning could cause a space leak because the string pool itself held a reference to every string, even if no other references existed. Apparently this is no longer true, at least as of JDK 1.6 (see, e.g., here).
For more on permgen, this is a decent overview of the topic. (Note: that link goes to a blog associated with a product. I don't have any association with the blog, the company, or the product, but the blog entry is useful and doesn't have much to do with the product.)
The literal string will remain in memory as long as the program is in memory.
str will be garbage collected, but the literal it is created from will not.
That makes perfect sense, since the string class is unloaded when the program is unloaded.
intern() method checks the availability of the object in String pool. If the object/literal is available then reference of it will be returned. If the literal is not there in the pool then object is loaded in the perm area (String pool) and then reference to it will be return. We have to use intern() method judiciously.
I heard that string object pool exists in the PermGC and when a string intern is executed, it checks the pool first to see if an equivalent string object exists, if it does not exist, it creates one and returns a reference to the pooled instance.
But here is my first question.
I think that object is created on the heap, especially in the young generation first. If it survives during few garbage collections, it moves to the old generation. can anybody explain how the string object goes to the pool that exists in the Perm GC?
second question:
String s = "test";
s = "test1";
If i reassign "test1" to a reference s and continue to use "test1", does it mean that "test" (created on the young generation) will be garbage collected?
third question:
How is the string object pool related to the runtime constant pool?
Thanks.
What makes you think the interned String first goes to the young generation? The String#intern() method is a native method. It's certainly very possible for an implementation to move it right into the permgen.
Second question: if there's no other references to that "test" String instance, it's eligible for garbage collection. Same story if it's interned. Even an interned String that no longer has any active references can be garbage collected. This might not have been the case in older JVMs, though. And it can be implementation-specific, I guess.
As for the third question, I do not know. All I know is that String literals from source code are placed into the same pool. If you were to construct a String that's equal to a String constant from source and then intern it, you'd be returned the instance that was used to represent the constant. Think of this as String literals having been interned right away.
EDIT: just read your initial few sentences again and I think I see the reason for the confusion. When you call intern() on a String, and no equal String is in the pool yet, then it's not first gonna construct an equivalent String. It'll just move the instance you called intern() on to the pool rather than returning a new reference. That's how it's stated in the JavaDoc.
Strings go to intern pool in two cases:
you explicitly call intern() method on the String object
you initialize it with a literal (you give the explicit content of the String), since Java automatically interns String literals.
The pool is organized as a table, once a String is interned it is added to the pool if the value is not yet present otherwise a reference to the existing entry is used.
"test" in your case is supposed to go to the pool and not to the young space, anyway cleanup of Strings not referenced anymore is performed there too (I cannot say if it is part of the same GC process used for the heap nor if this behavior is standard)
I have known that JVM maintains a string literal pool to increase performance and maintain JVM memory and learned that string literal is maintained in the string pool. But I want to clarify something related to the string pool and string object created on the heap.
Please correct me if my explanation is wrong.
String s = "abc";
If the above line is executed, "abc" string literal is added to the string pool if it does not exist in the pool. And string object is created on the heap and a reference s will point to the literal in the pool.
Questions:
Does this code create string object on the heap every time it is executed?
Does string literal pool maintain only string literals or does it maintain string object as well?
When does JVM decide that it needs to add string literal to the string pool? does it decide in the compile time or runtime?
I am not sure where exactly string object is created if it points to a string literal in the pool.
Thanks.
There is no "literal pool". Interned Strings are just normal heap objects. They may end up in the PermGen, but even then, they could eventually be garbage-collected.
The class file has a constant pool, which contains the String literals used in the class. When the class is loaded, String objects are created from that data, which is probably very similar to what String#intern does.
Does this code create string object on the heap every time it is executed?
No. There will be one String object that is being reused. It has been created when the class was loaded.
Does string literal pool maintain only string literals or does it maintain string object as well?
You can intern Strings as well. I assume that they are treated more or less the same.
When does JVM decide that it needs to add string literal to the string pool? does it decide in the compile time or runtime?
Literals are always "pooled". Other Strings need to have "intern" called on them. So in a way, the decision is made at compile-time.
Quoting documentation for String.intern()(emphasis mine)
All literal strings and string-valued constant expressions are
interned. String literals are defined in §3.10.5 of the Java Language
Specification
A pool of strings, initially empty, is maintained privately by the
class String.
When the intern method is invoked, if the pool already contains a
string equal to this String object as determined by the equals(Object)
method, then the string from the pool is returned. Otherwise, this
String object is added to the pool and a reference to this String
object is returned.
Thus,
Does this code create string object on the heap every time it is
executed?
Only one object is created for each unique interned string. All references share this immutable object.
Does string literal pool maintain only string literals or does it maintain string object as well?
There are no 'Literal Objects'. Literal string expressions when converted, are stored as regular String objects.Also, the pool contains all interned string objects. Both implicit (by using a string literal expression) and explicit (by calling .intern() on a String object).
When does JVM decide that it needs to add string literal to the string
pool? does it decide in the compile time or runtime?
I'm not sure.
I think there's something fundamental you're missing: the interned strings pool only contains String objects. Literals are not some sort of special object; at runtime they are just another String object.
Plus you can intern any String you want using String.intern(); it doesn't have to originate from a literal.
So regarding your questions:
No, there will be one String object allocated when the class is loaded.
It doesn't maintain any literals but rather String objects that were interned. Usually, those come from literals but in reality it could be any compile-time constant expression (String constant = "abc" + "def" would result in one String object "abcdef" at runtime).
They are compiled into the class file. So they are decided at compile time but obviously the objects themselves are created at runtime.
Does this code create string object on the heap every time it is executed?
Nope. Once created in the literal pool. The same referred again and again.
Does string literal pool maintain only string literals or does it maintain string object as well?
All are objects only, but objects created via assignment are put in pool where as the one created via new operator are put on heap.
When does JVM decide that it needs to add string literal to the string pool? does it decide in the compile time or runtime?
Whenever JVM comes across an expressions like
String str="Hello"; (string literal) or
String str="Hel" + "lo"; (string constant expression).
and the resultant string (str in this case) is not the pool, then in all such cases it adds the new string in the pool. This off course happens at runtime.
Check out this link.