StringTable详解

本文详细解析了Java中StringTable的工作原理,包括字符串池的概念、字符串拼接的机制、字符串延迟加载、intern()方法的使用及串池的性能调优策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

StringTable

1.什么是stringtable?

字符串池在JDK1.7之后存在于堆中的一块区域,String s1 = "abc"这样声明的字符串会放入字符串池中,String s1 = new String("abcd")会在字符串池有一个"abcd"的字符串对象,堆中也有1个,2个不同。

  • 字符串池可以避免重复创建字符串对象

    String s1 = "a";
    String s2 = "a";
    boolean isEqual = (s1 == s2);//为true,因为都是字符串池中的一个对象
    
    
  • 常量池中的字符串仅是符号,第一次用到时才变为对象

  • 它的结构为hash表结构,相同的字符串只存在一份

2. 字符串拼接原理

2.1字符串变量拼接

(代码中 s1 + s2)的原理是 new StringBuilder(),再调用它的append方法,最后调用它的toString(),实际是new String
在这里插入图片描述

2.2 字符串常量拼接

(代码中"a" + "b")的原理是编译期优化,编译器认为是常量,拼接结果唯一,去字符串池中找

3. 字符串延迟加载

利用idea中的Memory验证字符串的延迟加载,执行到的时候才加载,不是一次加载完(观察字符串个数)

  • Memory可以查看运行时每类对象的个数
    在这里插入图片描述

4. intern()–将串池中还没有的字符串对象放入串池

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

  1. 1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池, 会把串 池中的对象的引用返回
  2. 1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份, 放入串池, 会把串池中的对象返回
    在这里插入图片描述

5. 串池中的对象也会被GC回收

6. stringtable 性能调优

相关虚拟机参数

  • -XX:+PrintStringTableStatistics

  • -XX:StringTableSize

6.1 调整虚拟机参数-XX:StringTableSize

stringtable的数据结构为哈希表,如果程序里字符串常量的个数非常多,可以适当修改虚拟机参数-XX:StringTableSize(桶的个数,最小为1009)的大小:原理是增大桶的数量,减小冲突,提升效率

eg:逐行读取一个包含每行都是一个单词,共计48W个单词的文本文件,读取到一个字符串变量,并调用intern()方法加入到stringtable中,修改虚拟机参数StringTableSize分别为不设置,1009,200000观察读取花费的总时间。结论:stringtablesize越小,耗时越多.

/**
 * 演示串池大小对性能的影响
 * -Xms500m -Xmx500m -XX:+PrintStringTableStatistics -XX:StringTableSize=1009
 */
public class Demo1_24 {

    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);
        }
	}
}

6.2 考虑将字符串入池

前提是程序中存在大量(几十万,百万个)字符串,且有很多重复的情况


以上弄懂,下面这些就能搞明白啦

String s1 = "a";
String s2 = "b"; 
String s3 = "a" + "b"; 
String s4 = s1 + s2; 
String s5 = "ab"; 
String s6 = s4.intern();
//  System.out.println(s3 == s4); //false
System.out.println(s3 == s5);   //true
System.out.println(s3 == s6);
String x2 = new String("c") + new String("d"); 
String x1 = "cd"; 
x2.intern();
// 如果调换了【最后两行代码】的位置呢,如果是jdk1.6呢 
System.out.println(x1 == x2);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值