StringTable字符串常量池的垃圾回收跟踪案例

引言

很多人认为jvm字符串常量不会被回收的,其实这个说法的有误区的,我们通过一些jvm参数可以看到StringTable的垃圾回收。

案例说明

参数说明

参数 说明
-Xmx10m 堆空间大小
-XX+PrintStringTableStatistics 打印串池统计信息
-XX:+PrintGCDetails 打印GC日志详情
-verbose:gc 打印GC日志

先来一段空程序,我们使用参数运行:

    -Xmx10m -XX+PrintStringTableStatistics -XX:+PrintGCDetails -verbose:gc
 public static void main(String[] args) {
        int i=0;
        try {
        }catch (Throwable e){
            e.printStackTrace();
        }finally {
            System.out.println(i);
        }
    }

结果如下:

0
Heap
 PSYoungGen      total 2560K, used 1388K [0x00000007bfd00000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 2048K, 67% used [0x00000007bfd00000,0x00000007bfe5b100,0x00000007bff00000)
  from space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
  to   space 512K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007bff80000)
 ParOldGen       total 7168K, used 0K [0x00000007bf600000, 0x00000007bfd00000, 0x00000007bfd00000)
  object space 7168K, 0% used [0x00000007bf600000,0x00000007bf600000,0x00000007bfd00000)
 Metaspace       used 2927K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 319K, capacity 388K, committed 512K, reserved 1048576K
SymbolTable statistics:
Number of buckets       :     20011 =    160088 bytes, avg   8.000
Number of entries       :     11756 =    282144 bytes, avg  24.000
Number of literals      :     11756 =    455312 bytes, avg  38.730
Total footprint         :           =    897544 bytes
Average bucket size     :     0.587
Variance of bucket size :     0.587
Std. dev. of bucket size:     0.766
Maximum bucket size     :         6
StringTable statistics:
Number of buckets       :     60013 =    480104 bytes, avg   8.000
Number of entries       :       831 =     19944 bytes, avg  24.000
Number of literals      :       831 =     56304 bytes, avg  67.755
Total footprint         :           =    556352 bytes
Average bucket size     :     0.014
Variance of bucket size :     0.014
Std. dev. of bucket size:     0.118
Maximum bucket size     :         2

我们看到程序输出了堆信息,以及串池统计信息,需要了解的是我们的串池实现其实是类似Map的存储结构,里面的存储结构是数组的方式,每一个bucket就是一个数组结构,代表了里面存储的字符串个数。

Number of buckets       :     60013 =    480104 bytes, avg   8.000
Number of entries       :       831 =     19944 bytes, avg  24.000
Number of literals      :       831 =     56304 bytes, avg  67.755

我们假设如下,如果不存在gc,我们写入10万个字符,那么Number of entries 会增加到10万。我们调整程序如下:

  int i=0;
        try {
           for(int j=0;j<100000;j++){
               String.valueOf(j).intern();
               i++;
           }
        }catch (Throwable e){
            e.printStackTrace();
        }finally {
            System.out.println(i);
        }

运行查看结果:

[GC (Allocation Failure) [PSYoungGen: 2048K->496K(2560K)] 2048K->504K(9728K), 0.0015310 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 2544K->512K(2560K)] 2552K->528K(9728K), 0.0010023 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 2560K->480K(2560K)] 2576K->520K(9728K), 0.0013527 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
100000
Heap
 PSYoungGen      total 2560K, used 1295K [0x00000007bfd00000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 2048K, 39% used [0x00000007bfd00000,0x00000007bfdcbc60,0x00000007bff00000)
  from space 512K, 93% used [0x00000007bff00000,0x00000007bff78020,0x00000007bff80000)
  to   space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
 ParOldGen       total 7168K, used 40K [0x00000007bf600000, 0x00000007bfd00000, 0x00000007bfd00000)
  object space 7168K, 0% used [0x00000007bf600000,0x00000007bf60a000,0x00000007bfd00000)
 Metaspace       used 3095K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 339K, capacity 388K, committed 512K, reserved 1048576K
SymbolTable statistics:
Number of buckets       :     20011 =    160088 bytes, avg   8.000
Number of entries       :     12129 =    291096 bytes, avg  24.000
Number of literals      :     12129 =    467440 bytes, avg  38.539
Total footprint         :           =    918624 bytes
Average bucket size     :     0.606
Variance of bucket size :     0.606
Std. dev. of bucket size:     0.778
Maximum bucket size     :         6
StringTable statistics:
Number of buckets       :     60013 =    480104 bytes, avg   8.000
Number of entries       :     15285 =    366840 bytes, avg  24.000
Number of literals      :     15285 =    866120 bytes, avg  56.665
Total footprint         :           =   1713064 bytes
Average bucket size     :     0.255
Variance of bucket size :     0.267
Std. dev. of bucket size:     0.516
Maximum bucket size     :         4

我们发现日志显示发生了三次Yong gc,Number of entries 是15285,没有达到10万,说明了我们的串池是会发生GC的。

艾欧尼亚,昂扬不灭,为了更美好的明天而战(#^.^#)
原文地址:https://www.cnblogs.com/lovelywcc/p/14051039.html