[Java] String constant pool (implementation principle, garbage collection)

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

Guess you like

Origin blog.csdn.net/xiaoxiao_su123/article/details/113735944