JVM——String Table

JVM——String Table字符串常量池

String table又称为String pool,字符串常量池,其存在于堆中(jdk1.7之后改的)。最重要的一点,String table中存储的并不是String类型的对象,存储的而是指向String对象的索引,真实对象还是存储在堆中。

先看几道经典面试题:

String s1 = "a";        //在常量池中
String s2 = "b";        //在常量池中
String s3 = "a" + "b";  //在常量池中
String s4 = s1 + s2;    //字符串变量拼接的原理是 StringBuilder (jdk1.8)(相当于在堆中新建了一个对象)
String s5 = "ab";       //在常量池中直接查找"ab".字符串常量拼接的原理是编译期优化
String s6 = s4.intern();  // intern 方法,主动将串池中还没有的字符串对象放入串池。
// 问
System.out.println(s3 == s4);  
System.out.println(s3 == s5);
System.out.println(s3 == s6);
String x2 = new String("c") + new String("d");   //在堆中创建" c", "d" ,"cd"
String x1 = "cd"; //在串池中创建"cd".
x2.intern();      //主动将串池中还没有的字符串对象放入串池,如果有则并不会放入,如果没有则放入串池。两种情况都会把串池中的对象返回。
// 问,
System.out.println(x1 == x2);
如果调换了【最后两行代码】的位置呢

StringTable 特性

1.String Table 是哈希表结构,不能扩容。
2.常量池中的字符串仅是符号,第一次用到时才变为对象。
3.利用串池的机制,来避免重复创建字符串对象。
4.字符串变量拼接的原理是 StringBuilder (1.8)(相当于在堆中新建了一个对象)。
5.字符串常量拼接的原理是编译期优化。
6.可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池。
7.jdk1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池。(原来堆中的就没有了)两种情况都会把串池中的对象返回。
8.jdk1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池, 会把串池中的对象返回。

输出的结果应该为:

false
true
ture
false
ture

把这个面试题读懂之后,基本上StringTable的基础问题都可以自己解决了。

StringTable的垃圾回收及调优

字符串存在于堆内存中,只有当内存紧张时,才会触发垃圾回收。

(1) 它的底层由于是哈希表,我们可以设置-XX:StringTableSize=桶个数,一般大小设置大一点,可以减少哈希冲突,使StringTable的性能提高。
(2)考虑将字符串是否入池。例如存储地址,那么有可能不同的用户有相同的地址,这时我们就要加以区分,所以采用字符串的 intern()方法,减少字符串对于内存的占用。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

真真最可爱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值