Reprinted from: https://tangxman.github.io/2015/07/27/the-difference-of-java-string-pool/
In the memory allocation of Java, often hear a lot about the constant pool of the description, I began to look at the time is very vague, the online variety of the statement is simply too many, finally look at all kinds of information, finally is almost clear, a lot of online claims have problems, the author tries to distinguish these several concepts.
1. Global string pools (string pool also known as String literal pool)
The content in the global string pool is the completion of the class loading, the validation, the preparation phase after which a string object instance is generated in the heap, and then the reference value of the string object instance is stored in the string pool ( remember: A reference value is stored in a string pool instead of a specific instance object. Specific instance objects are stored in a piece of space that is opened up in the heap. ).
The string pool feature implemented in the Hotspot VM is a stringtable class, which is a hash table that contains a reference to the resident string (which is what we often say in double quotation marks), rather than the string instance itself. That is, after some string instances in the heap are referenced by this stringtable, they are equivalent to being given the identity "resident string". This stringtable is only one instance of each hotspot VM and is shared by all classes.
2.class file Chang (class constant pool)
As we all know, in addition to the class file contains the classes of the version, field, method, interface and other descriptive information, there is also a constant pool (constant pool table), for the compiler generated a variety of literal (Literal) and symbol references ( Symbolic References).
The literal is what we call a constant concept, such as a text string, a constant value declared final, and so on.
A symbol reference is a set of symbols that describe the target being referenced, and the symbol can be any form of literal, as long as it can be used without ambiguity to navigate to the target (it is distinguished from a direct reference, a direct reference is usually a local pointer to the method area, a relative offset, or a handle that can be positioned indirectly to the target). The following three types of constants are generally included:
- Fully qualified names for classes and interfaces
- Name and descriptor of the field
- The name and descriptor of the method
Each constant pool is a table with 11 different table structure data as shown in the table below, and the first bit of each table starts with a byte flag (value 1-12), which represents the constant type that the current constant belongs to.
Each type of constant type has a different structure, the specific structure of this article is not described, this article focuses on the concept of the three constant pool (readers want to learn more about the data structure of each constant type can see "deep understanding of Java Virtual Machine," chapter sixth).
3. Run a constant pool (runtime constant)
When a Java file is compiled into a class file, that is, the class constant pool that I referred to above is generated, and when is the runtime pool generated?
When the JVM executes a class, it must be loaded, connected, initialized , and the connection includes validation, preparation, and parsing of three phases. When the class is loaded into memory, the JVM stores the contents of the class constant pool in the run-time pool, so that the run-time pool is one of each class. In the above I also said that the class constant pool is the literal and symbolic references, that is, they do not save an instance of the object, but the object's symbolic reference value. After parsing (resolve), which is to replace the symbolic reference with a direct reference, the parsing process will query the global string pool, which is what we said above, to ensure that the strings referenced by the run-time pool are consistent with those referenced in the global string pool.
Give an example to illustrate:
1 String str1 = "abc" 2 string str2 = new String ("def" 3 String STR3 = "abc" ; 4 String str4 = Str2.intern (); 5 String str5 = "def" ; 6 System.out.println (str1 = = STR3); // true 7 System.out.println (str2 = = STR4); // false 8 System.out.println (STR4 = = STR5); // true
After the first compilation of the above program, in the class constant pool to hold some symbolic references, and then after the class loaded, the classes are stored in a constant pool of symbolic reference to the run-time pool, and then after the validation, preparation phase, The instance object that hosts the string is generated in the heap (that is, the "ABC" instance object pointed to by STR1 in the example above), and then the reference to the object is stored in the global string pool, which is stringtable, and finally in the parsing phase, To replace the symbolic reference in the run-time pool with a direct reference, query the stringtable directly to ensure that the reference value in the stringtable is consistent with the reference value in the run-time pool, which is probably the whole process.
Back to the program above, it is easy to explain the memory allocation process of the whole program, first, there will be an "ABC" instance in the heap, a reference value of "ABC" is stored in the global stringtable, and then when running the second sentence will generate two instances, a "Def" instance object , and Stringtable stored a "def" reference value, there is a new out of a "def" instance of the object, and the above is a different instance, when the resolution of STR3, looking for stringtable, there is "ABC" of the global resident string reference, So the reference address of STR3 is the same as the previous one, STR4 is to call the Intern () function at run time, return the reference value of "Def" in Stringtable, if not, add the reference value of str2, here, Stringtable already has the reference value of "Def" in it, so return the "def" reference value added to the stringtable in the new str2, and finally STR5 to the "def" that exists in stringtable at the time of parsing. Reference value, the following three printed values are easy to understand after such an analysis.
Summarize
- 1. The global constant pool has only one copy in each VM, and it holds the reference value of the string constant.
- The 2.class constant pool is at compile time for each class, and in the compile phase, a constant symbol reference is stored.
- 3. Running a constant pool is when the class load is complete, the symbol reference values in each class constant pool are dumped into the run-time pool, that is, each class has a run-time pool, which, after parsing, replaces the symbolic reference with a direct reference, consistent with the reference value in the global constant pool.
The distinction of several constant pools in Java