zoukankan      html  css  js  c++  java
  • StringTable结构以及基本调优

      JDK1.8中StringTable的底层类似于HashTable,由数组和链表实现,数组又称为桶数组。比如有这样一段代码:

    public class Demo4 {
        public static void main(String[] args) {
            int i = 0;
            System.out.println(i);
        }
    }

    我们设置虚拟机参数“-Xmx10m -XX:+PrintStringTableStatistics -XX:+PrintGCDetails -verbose:gc“,参数具体的意思是 设置堆内存大小为10M,输出StringTableStatistics信息,输出GC细节。运行代码控制台会有相应的输出,主要看下StringTable部分。默认桶的个数是60013,存储的字符串对象个数为1752,串池中字符串常量个数为也是1752,总的占用空间约为0.6M。上面代码只是输出i,但串池中常量个数为1752,那是因为类名、方法名等这些数据也是以常量的形式存在串池中。

    接着稍微改动代码:

    public class Demo4 {
        public static void main(String[] args) {
            int i = 0;
            // 往串池中添加100个字符串
            for (int j = 0; j < 100; j++) {
                String.valueOf(j).intern();
                i++;
            }
            System.out.println(i);
        }
    }

    这时候我们可以看到串池中字符串个数为1871,比默认多了100个。

    继续用上述代码做实验,这会for循环次数为10000,看控制台输出有什么变化。

    字符串个数为7451并不是11751,因为我们设置了堆内存大小为10M,存10000个字符串对象的话堆内存发生了MinorGC,将一些无用的对象回收了。

    调优

    • 调优主要是对StringTable大小的设置,如果程序中字符串数量非常多,那么可以将桶个数设置大一些,具体参数为 -XX:StringTableSize = 大小,默认是60013,最小是1009。有这样一段代码:
    public class Demo5 {
        public static void main(String[] args) throws IOException {
           try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("linux.words"), "utf-8"))) {
                String line = null;
                long start = System.nanoTime();
                while (true) {
                    line = reader.readLine();
                    if (line == null) {
                        break;
                    }
                    line.intern();
                }
                System.out.println("cost:" + (System.nanoTime() - start) / 1000000);
            }
        }
    }

      "linux.words"中有480000个字符串,读取文件然后将字符串放入串池,记录整个过程消耗时间,以ms为单位并且打印信息。默认桶个数下消耗时间为0.57秒。    

            

      我们设置 -XX:StringTableSize=1009再观察下消耗时间,变为了9.852秒。所以可根据业务场景来设置桶个数大小。 

            

    • 如果应用里有大量字符串并且存在很多重复的字符串,可以考虑使用intern()方法将字符串入池,而不是都存在Eden区中,这样字符串仅会占用较少的空间。

     

  • 相关阅读:
    Gamma correction 伽马校准及 matlab 实现
    特征描述子(feature descriptor) —— HOG(方向梯度直方图)
    特征描述子(feature descriptor) —— HOG(方向梯度直方图)
    opencv cvtColor dtype issue(error: (-215) )
    opencv cvtColor dtype issue(error: (-215) )
    python 命令行:help(),'more'不是内部或外部命令,也不是可运行的程序或批处理文件
    PES包格式
    Makefile编写 四 函数篇
    Makefile编写 三 伪目标的作用
    ELF文件和BIN文件
  • 原文地址:https://www.cnblogs.com/fly-bryant/p/13307712.html
Copyright © 2011-2022 走看看