求助>使用G1回收器,是否常量池回收特别慢?>
1回复
1月前

使用G1回收器,是否常量池回收特别慢?



Mac book pro 2021
jdk1.8
使用jvm参数
1.实验组

-Xmx2048m
-XX:MaxMetaspaceSize=1024m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=10
-XX:+PrintStringTableStatistics
-XX:StringTableSize=25000000
-XX:+PrintGC

运行代码

    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        for (int i=0; i<25000000; i++){
            UUID.randomUUID().toString().intern();
            if (i>=100000 && i%100000==0){
                System.out.println("i="+i);
            }
        }
        System.out.println(System.currentTimeMillis() - start);
    }

最终耗时:60141

2.对照组
硬件 软件 jvm参数 全部一致
代码稍作改动只修改 不去做String.intern()

    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        for (int i=0; i<25000000; i++){
      //      UUID.randomUUID().toString().intern();
            if (i>=100000 && i%100000==0){
                System.out.println("i="+i);
            }
        }
        System.out.println(System.currentTimeMillis() - start);
    }

最终耗时:46

请问为什么只是不把数据存放到常量池中可以快速这么多?是因为g1中常量池的垃圾回收和heap中的不一样吗?

745 阅读
请先登录,再评论

回复列表

https://a.perfma.net/img/2382850
鸠摩1月前

如果是研究inter()方法的执行效率,你应该把变量控制到最小,所以第2个对照组代码应该这么写:

public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        for (int i=0; i<25000000; i++){
            UUID.randomUUID().toString();
            if (i>=100000 && i%100000==0){
                System.out.println("i="+i);
            }
        }
        System.out.println(System.currentTimeMillis() - start);
    }

我运行的执行时间是50382,比不调用intern()稍等好一些,本来调用intern()方法就要消耗时间,而且还要查询字符串常量池,效率稍差一点是可以理解的