字符串常量池是jvm基于string不可变性构建的复用机制,非主动优化工具;字面量自动入池,new string()绕过池造成冗余;推荐直接使用双引号字面量,对高重复运行期字符串可谨慎调用intern(),jdk9+紧凑字符串自动节省内存。

Java 中字符串常量池本身不是“主动优化工具”,而是 JVM 基于 String 不可变性构建的一套复用机制。真正起优化作用的,是开发者对常量池特性的理解与合理使用——它不自动压缩内存,但能显著减少重复字符串对象数量。
字面量自动入池,避免 new String() 无谓堆分配
双引号定义的字符串(如 "OK"、"POST")在类加载时就进入常量池,后续相同字面量直接复用同一对象。而 new String("OK") 总是在堆中新建实例,即使内容重复,也绕过池、浪费空间。
- 推荐写法:
String method = "GET";→ 安全复用 - 避免写法:
String method = new String("GET");→ 多余对象,GC 压力增加 - 注意:
"GET".intern()对字面量无效(已驻留),纯属冗余调用
运行期显式 intern() 适用于高重复、长生命周期字符串
从数据库、配置文件或网络读取的字符串(如状态码、枚举值、协议字段),若内容重复率高且会被长期持有(如缓存、DTO 字段、Map 的 key),可主动调用 intern() 归一化引用。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 典型适用:
"SUCCESS"、"PENDING"、"USD"、"Q3" - 操作示例:
String status = rs.getString("status").intern(); - 效果:十万行数据中若有 8 万个 "SUCCESS",经 intern 后最多只保留 1 个对象,而非 8 万个独立实例
JDK 9+ 紧凑字符串进一步降低单字节字符内存开销
无需代码改动,JVM 自动启用:当字符串仅含 Latin-1 字符(ASCII 范围),内部用 byte[] 存储,每个字符占 1 字节,相比旧版 char[](2 字节)节省约 50% 内存。
- 生效条件:字符串内容全为 0–127 的字符(如英文、数字、常见符号)
- 透明运行:开发者无需感知,
length()、charAt()等方法行为完全一致 - 验证方式:可通过
Unsafe或 JOL 工具查看对象实际内存布局
慎用 intern():不是万能药,反而可能加重负担
intern() 是全局同步操作,且常量池位于堆中(JDK 7+),滥用会带来锁竞争、内存膨胀和 GC 风险。
- 禁止对唯一值调用:UUID、时间戳、随机 token —— 几乎不重复,intern 后白占空间且无法及时回收
- 避免循环内无条件调用:
for (...) { str.intern(); }→ 每次都查哈希表+加锁,性能反降 - 替代方案更可控:对业务明确的高频重复字段,用
ConcurrentHashMap<string string></string>显式缓存,可设大小上限与淘汰策略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










