Overview
String#intern
How to use.
How it does in jdk6 and jdk7.
How to instead.
栗子
使用场景猜想
当需要大量的字符串,并且不是直接声明的常量时,通过String#intern,有效使用常量池,复用String对象,可以增加程序的运行速度。
需要注意的是,StringPool是不可动态扩容的,所以过量使用String#intern会带来反效果。
解释
关于这个问题,我在stackOverFlow上做了提问
不过可能因为语言的关系,我对问题的描述不够清晰准确,导致没有获得我想要的答案。
当晚我在《深入理解Java虚拟机》这本书中,发现了解释。
JDK1.6中,String#intern是复制一份实例,放入常量池,并返回其引用。
而1.7中,则是将该实例的引用放入常量池,并返回。
jdk6 常量池在Perm区(永久代,也叫方法区),不能动态扩容,容量小,默认1009(而且PermGen很小,所以哪怕自己通过JVM参数指定,上限也很小)
jdk7 移到了Heap中
当然,常量池的位置在本问题中并不是决定性因素
优化
StringCache by ConcurrentHashMap
String.intern 耗时远大于 ConcurrentHashMap。
String.intern的耗时涨幅 与 池中字符串数量正相关,越多,耗时增加越多。
ConcurrentHashMap 的耗时几乎与池中数量同比例增长。
这些耗时 包括Initial intern, lookup same string, lookup equals string
ConcurrentHashMap 并发更好
使用自己的ConcurrentHashMap,你可以控制整个生命周期
h1. 参考文献
performance-penalty-of-string-intern
string-intern-in-java-6-7-8
http://www.wtoutiao.com/a/1023451.html