Preface
The string constant pool was in the permanent generation before java6. The name of the permanent generation tells us that the garbage collection effect here is very poor. If the string constant pool contains a large number of strings, it is easy to cause the permanent generation to overflow. Since java7, the string constant pool has been moved to the heap. The heap space is generally larger, and the recovery efficiency of the heap space is very high. Therefore, compared with the permanent generation, the memory overflow situation is greatly reduced after being placed in the heap space.
This article first observes the constant pool through the code, and then introduces how the string constant pool is implemented. This article uses jdk8.
Contents of this article
One, code experiment
The String.intern method is mainly used here. If the string is not in the constant pool, the reference of the string is placed in the constant pool and the reference is returned. If it is in the constant pool, the constant pool The reference of the string is returned.
public static void main(String[] args){
String s1=new String("hello");[1]
String s2=s1.intern();[2]
System.out.println(s1==s2);//false
System.out.println(s1=="hello");//false
System.out.println(s2=="hello");//true
String s3=new StringBuilder().append(s1).append(s2).toString();[3]
String s4=s3.intern();[4]
System.out.println(s3==s4);//true
System.out.println(s3=="hellohello");//true
}
operation result:
false
false
true
true
true
In code [1], because hello is a literal constant, java will put the string hello into the constant pool and create a String object in the heap at the same time. These two objects are different, and the string constant pool is already With the string hello, the code [2] directly returns the reference of the constant pool, so the false, false, and true printed below also appear.
Code [3] will create a string object hellohello in the heap, the string does not exist in the constant pool at this time, and then code [4] will put the reference in the heap into the constant pool, and return the reference , So s3 is equal to s4. The next literal constant hellohello is actually a reference to the code [4] put into the string constant pool, so the execution is also true.
Below I wrote a piece of code to verify that the string constant pool was moved to the heap area.
public static void main(String[] args)throws Exception{
String name = ManagementFactory.getRuntimeMXBean().getName();
System.out.println(name);
String pid = name.split("@")[0];
System.out.println("Pid is:" + pid); //打印PID
Thread.sleep(2000); //为了更好的观察现象
//s1和s2都是很长的字符串
String s1 = "qqq。。。";
String s2 = "qqqw。。。。";
System.out.print(s1.length());
System.gc();
s1 = null;
s2 = null;
Thread.sleep(2000); //为了更好的观察现象
System.gc();
Thread.sleep(2000); //为了更好的观察现象
System.gc();
Thread.sleep(2000); //为了更好的观察现象
}
The following is the result of running the jstat command:
PS C:\Program Files\Java\jdk1.8.0_161\bin> .\jstat.exe -gc 16524 1s
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
13312.0 13312.0 0.0 0.0 82432.0 11578.1 218624.0 0.0 4480.0 781.6 384.0 75.9 0 0.000 0 0.000 0.000
13312.0 13312.0 0.0 0.0 82432.0 1648.7 218624.0 1872.3 4864.0 3635.7 512.0 382.9 1 0.002 1 0.009 0.011
13312.0 13312.0 0.0 0.0 82432.0 1648.7 218624.0 1512.4 4864.0 3641.2 512.0 382.9 2 0.003 2 0.022 0.025
13312.0 13312.0 0.0 0.0 82432.0 0.0 218624.0 1508.7 4864.0 3641.3 512.0 382.9 3 0.004 3 0.042 0.046
A total of three garbage collections were performed. From the results, it is obvious that the total size of the old generation (OU) and the young generation (EU) is decreasing. The above results can indicate that the strings in the string constant pool are the same as ordinary objects. They are initially located in the young generation and will be moved to the old generation as the algebra increases.
Second, the realization principle of string constant pool
The string constant pool uses a hash table to store strings, similar to HashMap, the initial number of buckets is 60013 (you can use -XX:+PrintStringTableStatistics to print the results when the program exits, you can see the number of buckets), if stored There are many strings, you can use -XX:StringTableSize to increase the number of buckets to reduce conflicts.
Reference article
https://blog.csdn.net/weixin_38308374/article/details/110674739