JVM内存结构笔记04-字符串常量池-StringTable 垃圾回收案例

时间:2025-03-13 10:10:32

设置参数
-Xmx10m -XX:+PrintStringTableStatistics -XX:+PrintGCDetails -verbose:gc

/**
 * 演示 StringTable 垃圾回收
 * -Xmx10m -XX:+PrintStringTableStatistics -XX:+PrintGCDetails -verbose:gc
 */
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        int i = 0;
        try {

        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            System.out.println(i);
        }

    }
}

打印

0
Heap
 PSYoungGen      total 2560K, used 1955K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
  eden space 2048K, 95% used [0x00000000ffd00000,0x00000000ffee8c18,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
  to   space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
 ParOldGen       total 7168K, used 0K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000)
  object space 7168K, 0% used [0x00000000ff600000,0x00000000ff600000,0x00000000ffd00000)
 Metaspace       used 3293K, capacity 4564K, committed 4864K, reserved 1056768K
  class space    used 361K, capacity 388K, committed 512K, reserved 1048576K
SymbolTable statistics:
Number of buckets       :     20011 =    160088 bytes, avg   8.000
Number of entries       :     13355 =    320520 bytes, avg  24.000
Number of literals      :     13355 =    594648 bytes, avg  44.526
Total footprint         :           =   1075256 bytes
Average bucket size     :     0.667
Variance of bucket size :     0.668
Std. dev. of bucket size:     0.817
Maximum bucket size     :         6
StringTable statistics:
Number of buckets       :     60013 =    480104 bytes, avg   8.000
Number of entries       :      1745 =     41880 bytes, avg  24.000
Number of literals      :      1745 =    177296 bytes, avg 101.602
Total footprint         :           =    699280 bytes
Average bucket size     :     0.029
Variance of bucket size :     0.029
Std. dev. of bucket size:     0.171
Maximum bucket size     :         2

重点观察其中的StringTable statistics

1.创建100个字符串(不会触发垃圾回收)

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        int i = 0;
        try {
            for (int j = 0; j < 100; j++) { // j=100, j=10000,100000
                String.valueOf(j).intern();
                i++;
            }
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            System.out.println(i);
        }`
    }
}

打印

StringTable statistics:
Number of buckets       :     60013 =    480104 bytes, avg   8.000
Number of entries       :      1845 =     44280 bytes, avg  24.000
Number of literals      :      1845 =    182096 bytes, avg  98.697
Total footprint         :           =    706480 bytes
Average bucket size     :     0.031
Variance of bucket size :     0.031
Std. dev. of bucket size:     0.175
Maximum bucket size     :         2

可以发现Number of entries与Number of literals新增了100个字符串对象

2.创建10000个字符串(触发垃圾回收)

[GC (Allocation Failure) [PSYoungGen: 2048K->488K(2560K)] 2048K->786K(9728K), 0.0359746 secs] [Times: user=0.00 sys=0.00, real=0.04 secs] 
10000
Heap
 PSYoungGen      total 2560K, used 851K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
  eden space 2048K, 17% used [0x00000000ffd00000,0x00000000ffd5ac98,0x00000000fff00000)
  from space 512K, 95% used [0x00000000fff00000,0x00000000fff7a020,0x00000000fff80000)
  to   space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
 ParOldGen       total 7168K, used 298K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000)
  object space 7168K, 4% used [0x00000000ff600000,0x00000000ff64a8b0,0x00000000ffd00000)
 Metaspace       used 3296K, capacity 4564K, committed 4864K, reserved 1056768K
  class space    used 361K, capacity 388K, committed 512K, reserved 1048576K
SymbolTable statistics:
Number of buckets       :     20011 =    160088 bytes, avg   8.000
Number of entries       :     13356 =    320544 bytes, avg  24.000
Number of literals      :     13356 =    594664 bytes, avg  44.524
Total footprint         :           =   1075296 bytes
Average bucket size     :     0.667
Variance of bucket size :     0.668
Std. dev. of bucket size:     0.817
Maximum bucket size     :         6
StringTable statistics:
Number of buckets       :     60013 =    480104 bytes, avg   8.000
Number of entries       :      8582 =    205968 bytes, avg  24.000
Number of literals      :      8582 =    505552 bytes, avg  58.908
Total footprint         :           =   1191624 bytes
Average bucket size     :     0.143
Variance of bucket size :     0.154
Std. dev. of bucket size:     0.393
Maximum bucket size     :         3

因为创建的字符串对象没有被引用,所以无用的字符串被垃圾回收