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?
7 Answers
... why does Java create new Object each time we create a string using the
newkeyword 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.
6 Comments
String with == bugs...subString return strings with new backing stores in cases where they would use less than half the original, but borrow the original otherwise, or of having separate subString methods for cases where the copy was expected to outlive the original versus cases where it wasn't?substring implementation sharing the array and a smart garbage collector knowing how to compact those strings if the original large string becomes unreachable. Today’s JVMs have a garbage collector that has special knowledge about strings and their character array as it will force sharing of arrays for equal strings. Nevertheless, having the cheap substring also implies that each String has to carry an extra offset and length field which have to be respected by every other string operation…string behave as distinct type in the language which would typically hold a reference, and allow coercion to Object or StringObject, but would implement == as value equality, and would offer no guarantee as to when (StringObject)string1 == (StringObject)string1 would yield true or false [a situation similar to e.g. (Short)x == (Short)x]. That would have allowed an implementation to efficiently use different kinds of objects for different...char[], byte[], or various kinds of heap objects) and make substitutions as convenient. For example, a ConcatenatedString could contain a String[] whose first element if non-null would represent its content, and whose remaining elements if non-null would identify constituents. Using a ConcatenatedString for any purpose requiring a linear string would cause the system to physically concatenate its pieces and store a reference to the linear string (in case it's needed again) but concatenating a string and then concatenating it to something else...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.
Comments
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.
Comments
To take advantage of string pooling you need to use String#intern instead of new.
4 Comments
String foo = "foo"; String bar = new String("foo").intern();, bar == foo, so the instance created by new String("foo") is no longer referenced.new String("foo") will have no reference to it and will be eligible for GCFollowing 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")
4 Comments
s on the first line points to this. On line two, a new String object is constructed, with the constant String object passed as a parameter. docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5To 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).
6 Comments
Strings from the runtime pool can (and will) get garbage collected just like any other unused string. Only if they happen to match an existing constant from a class file, that constant won’t get collected, which is no issue as it exists anyway. The main reason not to use intern() on every string is that it is not cheap, as it will incorporate hashing and, even worse, the size of the table of interned strings is fixed which raises the likelihood of collisions (and before Java7u40, it’s size was ridiculous small).intern() like being the same. Calling intern() does not suddenly modify the class’ byte code. Strings which are interned but don’t match a literal, can get garbage collected without problems. And since the question was about strings created via new, we are not talking about literals. But if we consider that the string could match a literal, allowing garbage collection of the new string is a strange argument as that means solving a problem that doesn’t exist otherwise, i.e. when the existing string is returned and no new one created.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.
newmeans...