Java StringTable

一. 特点

1. 常量池中的字符串仅是符号,第一次用到时才变为对象

2. 利用串池的机制,来避免重复创建字符串对象

3. 字符串变量拼接的原理是 StringBuilder1.8),StringBuilder的toString()方法实际上是new出来的String

4. 字符串常量拼接的原理是编译期优化,"a"+"b"就当成"ab"创建

String s1="a";
String s2="b";
String s3="ab";
String s4=s1+s2;
String s5="a"+"b";
System.out.println(s3==s4);//false StringBuilder
System.out.println(s3==s5);//true 编译时优化

5. 可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池 1.8

//  ["ab", "a", "b"]
public static void main(String[] args) {

    String s = new String("a") + new String("b");//此时串池只有"a","b"

    // 堆  new String("a")   new String("b") new String("ab")
    String s2 = s.intern(); // 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池(1.6是复制一份), 会把串池中的对象返回

    String s3 = "ab";
    System.out.println( s2 == s3);//true
    System.out.println( s == s3 );//true
}
    

 

二. 位置

1.6时StringTable在永久代的常量池里,1.8之后在堆中(方法去变成了直接内存里的元空间);

因为旧方案回收效率不高,会占用大量内存,而放到堆中只要触发Minor gc就会清理

 

三. 调优

StringTable底层实现类似于HashMap,数组+链表

当字符串常量数据量很大时,可以调整-XX:StringTableSize=桶个数,让它稍大一点,这样平均每个桶对应的链表不会太长

posted @ 2021-03-08 14:18  Kinghao0319  阅读(173)  评论(0编辑  收藏  举报