参考以下代码配置参数并运行。

/**
 * 演示 StringTable 垃圾回收
 * -Xmx10m -XX:+PrintStringTableStatistics -XX:+PrintGCDetails -verbose:gc
 */
public class Demo1_7 {
    public static void main(String[] args) throws InterruptedException {
        int i = 0;
        try {
            for (int j = 0; j < 100000; j++) { // j=100, j=10000
                String.valueOf(j).intern();
                i++;
            }
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            System.out.println(i);
        }

    }
}

打印信息如下

[GC (Allocation Failure) [PSYoungGen: 2048K->488K(2560K)] 2048K->875K(9728K), 0.0028226 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [PSYoungGen: 2536K->512K(2560K)] 2923K->958K(9728K), 0.0039494 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 2560K->512K(2560K)] 3006K->1006K(9728K), 0.0020900 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
...
StringTable statistics:
Number of buckets       :     60013 =    480104 bytes, avg   8.000
Number of entries       :     26231 =    629544 bytes, avg  24.000
Number of literals      :     26231 =   1548152 bytes, avg  59.020
Total footprint         :           =   2657800 bytes
Average bucket size     :     0.437
Variance of bucket size :     0.418
Std. dev. of bucket size:     0.646
Maximum bucket size     :         4

string table底层是hashtable,是采用数组加链表的形式存储数据,可以看到存储字符串的桶的数量为60013个,字符串的数量为26231个。我们实际上创建的字符串个数是10 0000个,为什么打印出来的数量不符合呢?根据打印信息,原来是因为触发了GC操作。