String constant pool in Java
There are two forms of string object creation in Java. One is a literal form, such as String str = "droid"; and the other is a standard method of constructing objects using new, such as String str = new String("droid");. We often use these two methods when writing code, especially the literal method. However, these two implementations actually have some differences in performance and memory usage. All this is due to the fact that the JVM maintains a special memory in order to reduce the repeated creation of string objects, which is a string constant pool or string literal pool.
How it works
When a string object is created in the literal form in the code, the JVM will first check the literal. If there is a reference to a string object with the same content in the string constant pool, the reference will be returned. Otherwise, the new string object will be created, and then the reference will be placed into the string constant pool and the reference will be returned.
Give an example
Literal creation form
String str1 = "droid";
JVM detects this literal, here we think that no object with content is droid exists. The JVM cannot find the string object with droid content through the string constant pool, so it will create this string object, and then put the reference of the object you just created into the string constant pool, and return the reference to the variable str1.
If there is a code like this next
String str2 = "droid";
Similarly, the JVM still needs to detect this literal. By searching for the string constant pool, the JVM found that the content is "droid" string object exists, so it returns the reference of the existing string object to the variable str2. Note that new string objects will not be recreated here.
Verify whether str1 and str2 point to the same object, we can use this code
System.out.println(str1 == str2);
The result is true.
Create with new
String str3 = new String("droid");
When we use new to construct string objects, new string objects will be created regardless of whether there are references to objects with the same content in the string constant pool. So let's use the following code to test it.
String str3 = new String("droid");
System.out.println(str1 == str3);
The result is false as we think, indicating that the two variables point to different objects.
intern
For the string object created with new above, if you want to add a reference to the string constant pool, you can use the intern method.
After calling intern, first check whether there is a reference to the object in the string constant pool. If it exists, return this reference to the variable, otherwise the reference will be added and returned to the variable.
String str4 = str3.intern();
System.out.println(str4 == str1);
The output result is true.
Difficult problems
Prerequisites?
The prerequisite for implementing string constant pools is that String objects in Java are immutable, which can safely ensure that multiple variables share the same object. If the String object in Java is variable, and one reference operation changes the object's value, other variables will also be affected, obviously this is unreasonable.
Reference or object
This question is most common when a string constant pool is stored in a reference or an object. The string constant pool stores object references, not objects. In Java, objects are created in heap memory.
Update verification, many comments received are also discussing this issue, and I simply verify it. Verify the environment
22:18:54-androidyue~/Videos$ cat /etc/os-releaseNAME=FedoraVERSION="17 (Beefy Miracle)"ID=fedoraVERSION_ID=17PRETTY_NAME="Fedora 17 (Beefy Miracle)"ANSI_COLOR="0;34"CPE_NAME="cpe:/o:fedoraproject:fedora:17"22:19:04-androidyue~/Videos$ java -versionjava version "1.7.0_25"OpenJDK Runtime Environment (fedora-2.3.12.1.fc17-x86_64)OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
Verification idea: The following Java program reads a video file of 82M size and performs intern operations in the form of a string.
22:01:17-androidyue~/Videos$ ll -lh | grep why_to_learn.mp4-rw-rw-r--. 1 androidyue androidyue 82M Oct 20 2013 why_to_learn.mp4
Verification code
import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;public class TestMain { private static String fileContent; public static void main(String[] args) { fileContent = readFileToString(args[0]); if (null != fileContent) { fileContent = fileContent.intern(); System.out.println("Not Null"); } } private static String readFileToString(String file) { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(file)); StringBuffer buff = new StringBuffer(); String line; while ((line = reader.readLine()) != null) { buff.append(line); } return buff.toString(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (null != reader) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; }}Since the string constant pool exists in the permanent generation in heap memory, it is suitable before Java 8. We verify by setting a permanent generation of a small value. If the string object exists in the string constant pool, a java.lang.OutOfMemoryError permgen space error must be thrown.
java -XX:PermSize=6m TestMain ~/Videos/why_to_learn.mp4
Running the proof program does not throw OOM, but this cannot prove that it is stored as an object or a reference.
But this at least proves that the actual content object char[] of the string is not stored in the string constant pool. In this case, it is not so important that the string constant pool stores references to string objects or string objects. But individuals still tend to store references.
Pros and cons
The advantage of string constant pooling is to reduce the creation of strings of the same content and save memory space.
If you have to say the disadvantages, it is to sacrifice CPU computing time to exchange space. CPU calculation time is mainly used to find whether there are references to objects with the same content in the string constant pool. However, its internal implementation is HashTable, so the calculation cost is low.
GC recycling?
Because the string constant pool holds a reference to the shared string object, does this mean that these objects cannot be recycled?
First of all, the shared objects in the question are generally smaller. As far as I have verified, there was indeed such a problem in earlier versions, but with the introduction of weak references, this problem should be gone at present.
Regarding this issue, you can learn more about this article. Interned Strings: Java Glossary
Use intern?
The prerequisite for using intern is that you know that you really need to use it. For example, we have a record of millions here, where a certain value of the record is California, USA many times. We do not want to create millions of such string objects. We can use intern to keep only one copy in memory. For a more in-depth understanding of intern, please refer to the in-depth analysis of String#intern.
Are there always exceptions?
Do you know the following code will create several string objects and save several references in the string constant pool?
String test = "a" + "b" + "c";
The answer is that only one object is created and only one reference is saved in the constant pool. We use Javap decompilation and take a look at it.
17:02 $ javap -c TestInternedPoolGCCompiled from "TestInternedPoolGC.java"public class TestInternedPoolGC extends java.lang.Object{public TestInternedPoolGC(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: returnpublic static void main(java.lang.String[]) throws java.lang.Exception; Code: 0: ldc #2; //String abc 2: store_1 3: returnHave you seen it? In fact, during the compilation period, these three literals have been synthesized into one. This is actually an optimization that avoids creating redundant string objects and does not have string stitching problems. For string stitching, you can view Java details: string stitching.
The above is a compilation of the information about string constant pools in Java. We will continue to add relevant information in the future. Thank you for your support for this site!