String.intern():檢查字符串常量池中是否存在內容相同的字符串,若存在返回池中引用;否則將該字符串放入池並返回引用。目的是減少重複字符串對象,節省記憶體。
| 版本 | 常量池位置 | 默認桶數量 | 關鍵變化 |
|---|---|---|---|
| JDK 6 | PermGen(永久代) | 1009 | 大小固定,易 OOM |
| JDK 7u40 前 | Heap(堆) | 1009 | 移出 PermGen,受堆大小限制 |
| JDK 7u40+ | Heap | 60013 | 桶數大幅增加,減少哈希衝突 |
| JDK 8+ | Heap | 60013 | PermGen 移除,改為 Metaspace |
public class StringPoolTest {
public void testStringPoolWithLongString() {
long i = 0;
while (true) {
String longString = "This is a very long string... " + i;
longString.intern();
i++;
}
}
public static void main(String[] args) {
new StringPoolTest().testStringPoolWithLongString();
}
}

intern() 易導致 OutOfMemoryError: PermGen space

-Xmx 限制,空間彈性大得多intern(),性能顯著下降且極易 OOM。-XX:StringTableSize=60013(JDK 7u40+ 默認值),可根據預估不同字符串數量調大(需為質數),減少哈希衝突提升查找速度。ConcurrentHashMap 自行維護池,可控性更強。String.intern() 的行為隨 JVM 版本劇烈變化。JDK 6 時代是「危險區」,JDK 7+ 遷移至堆後成為「實用工具」。理解底層內存模型演變,才能在正確場景下正確使用,避免生產事故。