StringTable
定义
俗称串池,用于存储字符串类型的引用。
存储位置
JDK1.6的时候存储在永久代的常量池中,JDK1.8为了提高回收效率,把StringTable存放在堆中。
结构
存储结构为HashTable,也就是数组+链表的形式,不允许扩容。
使用Hash值来确定元素应该放在数组的哪一个位置,当Hash值相同时称为哈希冲突,这时首先判断hash值相同的元素是否相同,如果是的话拒绝插入,如果不是的话则会在链表中插入元素。
特性
- 字符串会延迟加载,执行到该代码的时候才会加载到StringTable中
- 利用串池机制防止重复创建字符串对象
- 变量拼接的原理是StringBuilder
- 常量拼接的原理是编译器优化
创建String两种方式的区别
使用new String()创建字符串变量
- 查找串池中是否有该字符串的值,串池没有该值,则在串池中新增这个字符串的值,然后在堆中创建该对象
- 查找串池中是否有该字符串的值,串池已经存在该值,直接在堆中创建该对象
使用String a = "xx"创建字符串变量
查找串池是否存在该字符串对象,没有的话在串池新增该字符串的值,有的话直接引用串池里面的对象。
注意事项
两个字符串变量拼接会调用StringBuilder的toString方法,相等于使用new创建,因此该字符串对象会放入堆里面。但是由于这是动态拼接,不会放入StringTable(new String的参数是一个常量的时候会放入StringTable中)
intern方法
作用
尝试把该字符串对象放入串池当中,如果没有则直接放入,如果串池当中存在相同的值,则不会把该对象放入,返回串池中的对象。(针对jdk1.8)
jdk1.6如果串池没有该对象的话,会复制一个新的对象再放入串池
性能优化
- 字符串常量较多的话,把StringTable的桶数量增加,可以提高效率(调整-XX:StringTableSize参数)
- 使用入池不可重复的机制,减少字符串重复浪费内存