No, typically you can not "destroy reference from String pool in Java" manually.
The main reason I suppose why you are targeting it is to avoid out of memory errors. In Java 6 days all interned strings were stored in the PermGen – the fixed size part of heap mainly used for storing loaded classes and string pool. Besides explicitly interned strings, PermGen string pool also contained all literal strings earlier used in your program. The biggest issue with string pool in Java 6 was its location – the PermGen. PermGen has a fixed size and can not be expanded at runtime. You can set it using -XX:MaxPermSize=N option. This would lead to memory leaks and out of memory errors.
In Java 7 – the string pool was relocated to the heap. It means that you are no longer limited by a separate fixed size memory area. All strings are now located in the heap, as most of other ordinary objects.
You may also increase the string pool size by configuring -XX:StringTableSize=N. If you are not sure about the string pool usage, try -XX:+PrintStringTableStatistics JVM argument. It will print you the string pool usage when your program terminates.
In JDK, there is also a tool named jmap which can be used to find out number of interned strings in your application.
jmap -heap process_id
Eg:
jmap -heap 18974
Along with other output, this command also outputs number of interned strings and the space they occupy "xxxxxx interned Strings occupying xxxxxx bytes."
The rules for garbage collection of objects in the String pool are the same as for other Strings or any other object. But the fact that the String objects that correspond to String literals mostly are always reachable since there is an implicit reference to the string object in the code of every method that uses the literal and so typically they are not candidates for garbage collection. However, this is not always the case. If the literal was defined in a class that was dynamically loaded (e.g. using Class.forName(...)), then it is possible to arrange that the class is unloaded. If that happens, then the String object for the literal will be unreachable, and will be reclaimed when the heap containing the interned String gets GC'ed.
Answer from Robin Rizvi on Stack Overflowjava - How to clear the entry from String Literal Pool - Stack Overflow
java - String Constant Pool - Stack Overflow
String constant pool
Java - String & constant pool - Stack Overflow
String literals (WeakHashMap) are also stored in heap memory called the "permgen" heap. need to configure in JVM to find and collect dynamically loaded classes that are no longer needed, and this may cause String literals to be garbage collected. and or when JVM performas the Full gc.
An excerpt from How does Java store Strings and how does substring work internally?:
Strings in the pool can be garbage collected (meaning that a string literal might be removed from the pool at some stage if it becomes full)
Maybe this will aid your understanding:
String literal = "test";
String one = new String(literal);
String two = "test";
System.out.println(literal == two); //true
System.out.println(one == two); //false
In the example you posted:
String one = new String("test");
String two = "test";
the reference passed to the constructor String(String) has the same value as the reference two due to interning. However, the string itself (referenced by these two references) is used to construct a new object which is assigned to reference one.
In this example, there are exactly two Strings created with the value "test": the one maintained in the constant pool and referenced whenever you use the literal "test" in an expression, and the second one created by the "new" operator and assigned to the reference one.
Edit
Perhaps you're confused about this statement:
When the compiler encounters a String literal, it checks the pool to see if an identical String already exists.
Note that this might be more clearly stated as:
When the compiler encounters a String literal, it checks to see if an identical String already exists in the pool.
Strings are only put in the pool when they are interned explicitly or by the class's use of a literal. So if you have, for example, this scenario:
String te = "te";
String st = "st";
String test = new String(te) + new String(st);
then while a String will exist with the value test, said String will not exist in the pool as the literal "test" has never occurred.
//Creates a new object even if one exists in the pool
String s1 = new String("Tendulkar");
// makes a new object string and then the reference is available to the pool
String s2 = s1.intern();
//this object is not created but references the address present in the pool
String s3 = "Tendulkar";
System.out.print(s1==s2); // results in false
System.out.print(s2==s3); //very very true !!!
I am preparing for the OCA Java 8 exam and I am confused in regards to strings and what happens when they're created. I understand that Strings are created in one of two methods: by "new" keyword and by String literals. When created by String literals, Java first looks inside the String constant pool to see if there are any matching Strings, if non are available then a new String object is created and a reference to it is returned. When created by the "new" keyword a new String object is created in the non pool heap. Both String objects are not related even if both String objects have the same characters. I hope I have this concept correct. My question is, when creating a String object by means of the "new" keyword, does the String object's created by the "new" keyword String literal go inside the String constant pool and becomes available for reuse or those it permanently stay outside the pool? I feel that because it's created in the non pool heap and because you can create Strings using both methods and both objects won't equal to be the same but rather point to different references, Strings created using the "new" keyword will create a non pool String and the String stays outside the pool and cannot be use by any other reference variable?
You can use new, but it will be a little tricky that you specify using the "intern" method of String. like this:
String a = "ABC";
String b = new String("ABC").intern();
System.out.println(a == b);
Output is true, if no "intern", then it is a copy from the constant pool.
String a = "ABC";
String b = new String("ABC");
System.out.println(a == b);
output is false. If you looks into the prototype of this String constructor, it shows that:
/**
* Initializes a newly created {@code String} object so that it represents
* the same sequence of characters as the argument; in other words, the
* newly created string is a copy of the argument string. Unless an
* explicit copy of {@code original} is needed, use of this constructor is
* unnecessary since Strings are immutable.
*
* @param original
* A {@code String}
*/
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
Latter is right. To create a String instance from literal using new() is absolutely meaningless.