Touch java constant pool and java constant
The java constant pool is a persistent topic and the interviewer's favorite. There are a variety of things on the subject. This time, I have heard about the constant pool.
Theory
The following is a poor description of jvm Virtual Memory Distribution:
1 String s1 = "Hello"; 2 String s2 = "Hello"; 3 String s3 = "El" + "lo "; 4 String s4 = "El" + new String ("lo"); 5 String s5 = new String ("Hello"); 6 String s6 = s5.intern (); 7 String s7 = "H"; 8 String s8 = "ello"; 9 String s9 = s7 + s8; 10 11 System. out. println (s1 = s2); // true12 System. out. println (s1 = s3); // true13 System. out. println (s1 = s4); // false14 System. out. println (s1 = s9); // false15 System. out. println (s4 = s5); // false16 System. out. println (s1 = s6); // true
First of all, in java, the = Operator is used directly to compare the reference addresses of two strings, not the comparison content. For the comparison content, use String. equals ().
S1 = s2 This is very easy to understand. When s1 and s2 are assigned a value, they all use the string literal. In other words, the vernacular point means that the string is directly written to death. during compilation, this type of literal will be directly put into the constant pool of the class file to achieve reuse. After loading the pool of runtime frequent values, s1 and s2 point to the same memory address, so they are equal.
S1 = s3 there is a pitfall in this place. Although s3 is a dynamically spliced string, all components involved in the concatenation are known literally. during compilation, this concatenation will be optimized, and the compiler will help you spell it out directly. Therefore, String s3 = "El" + "lo"; is optimized to String s3 = "Hello ";, so s1 = s3 is true.
S1 = s4 is of course not equal. s4 is also spliced, but the new String ("lo") is not a known literal and an unpredictable part, the compiler will not be optimized, and the results can be determined only when running.String unchangedTheorem: the ghost knows where s4 is allocated, so the address must be different. Configure the following diagram to clarify the concept:
You must pay attention to the behaviors during the compilation period to better understand the constant pool.
Constants in the runtime constant pool are basically derived from the constant pool in each class file.
When the program is running, unless you manually add a constant to the constant pool (such as calling the intern method), the jvm will not automatically add the constant to the constant pool.
The above description only involves the String constant pool. In fact, there are also integer constant pools and floating point constant pools. However, they are similar, but the constant pools of numerical types cannot be manually added, the constant in the pool has been determined when the program starts. For example, the constant range in the integer constant pool is-128 ~ 127. Only the number in this range can be used in the constant pool.
Practice
With so many theories, let's touch the real constant pool.
As mentioned above, there is a static constant pool in the class file, which is generated by the compiler to store the literal volume in the java source file (this article only focuses on the literal volume ), suppose we have the following java code:
1 String s = "hi";
This is simple for convenience! After the code is compiled into a class file, use winhex to open the class file in binary format.
1 // retain reference to Prevent automatic garbage collection 2 List <String> list = new ArrayList <String> (); 3 4 int I = 0; 5 6 while (true) {7 // manually add the constant 8 list to the constant pool through the intern method. add (String. valueOf (I ++ ). intern (); 9}
The program immediately throws an Exception: Exception in thread "main" java. lang. outOfMemoryError: PermGen space. PermGen space is the method area, which is sufficient to indicate that the constant pool is in the method area.
In jdk8, the method area is removed and replaced with the Metaspace area. Therefore, we need to use the new jvm parameter-XX: MaxMetaspaceSize = 2 M. We still run the above Code and throw: java. lang. outOfMemoryError: Metaspace exception. Similarly, the runtime frequent pool is divided into Metaspace areas. For details about the Metaspace area, please search for it by yourself.
All the code in this article is tested and passed in jdk 7 and jdk 8. jdk may be slightly different in other versions. Please explore it on your own.
References:Deep understanding of Java Virtual Machine-advanced jvm features and best practices