今天群里讨论了一下占小狼的一篇博客http://www.jianshu.com/p/c14364f72b7e
代码如下
public class Test {
public static void main(String[] args) {
String sq1 = new StringBuilder().append("aa").append("bb").toString();
System.out.println(sq1 == sq1.intern());//true
String sq2 = new StringBuilder("aa").append("bb").toString();
System.out.println(sq2 == sq2.intern());//false
String sq3 = new StringBuilder().append("ja").append("va").toString();
System.out.println(sq3 == sq3.intern());//false
}
}
上面三个结果,看出了什么。其实看的一脸蒙蔽。
讨论的结果是在1.8环境下intern()
常量池的内存在永久带中分配,永久带和java堆的内存是物理隔离的,执行intern()时,如果常量池不存在该字符串,虚拟机会在常量池中复制该字符串,并返回引用。如果有相同的字符串,则返回第一次创建的引用。
具体的分析看占小狼的博客。这个有个JVM参数
-XX:StringTableSize=____
我们在调用String.intern()的时候会往hashtable中插入一项,这个table就是StringTable,使用最多的是序列号反序列化场景,为了避免同一个字符串被多次创建。保证每一次通过String.intern()返回同一个字符对象。
如果这个参数设置的太小,带来的问题就是hash碰撞。这样就比较消耗cpu,jdk1.6之后出现了rehash,但是表的size小的话,只能换来不断的rehash,因此性能比较差,所以一般这个参数设置的稍微大点的质数。
网友评论