目录
看下面的这段代码
String s1="a"; //常量池中
String s2="b"; //常量池中
String s3="ab"; //常量池中
String s4=s1+s2; //堆中 通过new String()出来的
System.out.println(s3==s4); //false 值一样,地址不一样
String s5="a"+"b"; //常量池中
System.out.println(s3==s5); //true '+'优先级高于'='
String s6=s4.intern(); //因为'ab'已经存在,所以没有放入常量池,返回之前的引用
System.out.println(s3==s6); //true intern就是把该对象放入串池,返回该对象的引用
System.out.println(s4==s6); //false 因为串池中有'ab',所以没有放入,因此虽然值一样,但是引用不一样,一个是常量池的引用,一个是堆的引用,如果将该对象放入了串池,那么两者都是堆的引用
说明:
常量池中的字符串仅是符号,第一次用到时才变为对象
利用串池的机制,来避免重复创建字符串对象
字符串变量拼接的原理是,StringBuilder(1.8)
字符串常量拼接的原理是编译期优化
可以使用intern方法,主动将串池中还没有的字符串放入串池
1.8:将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池,会把串池中的对象返回
1.6:将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池,会把串池中的对象返回
StringTable位置
1.8:字符串常量池放在元空间中
1.6 字符串常量池放在永久代中
StringTable垃圾回收
Java中不仅仅只有堆里面的对象才会被垃圾回收(当不再使用就被回收),字符串常量池也会被垃圾回收,当内存不够用的时候就会清理掉之前的一些字符串。
StringTable性能调优
调整 -XX:StringTableSize=桶个数(>=1009) 桶越多越快
考虑将字符串对象入池(String.intern()),当有大量重复的字符串时。