🚀 作者主页: 有来技术
🔥 开源项目: youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template
🌺 仓库主页: GitCode︱ Gitee ︱ Github
💖 欢迎点赞 👍 收藏 ⭐评论 📝 如有错误敬请纠正!
前言
在 Java 开发中,字符串常量池(String Constant Pool)是一个关键但容易被忽略的优化机制。周志明老师在《深入理解 Java 虚拟机:JVM 高级特性与最佳实践(第 3 版)》的 2.4.3 章节中提出了一个与方法区和常量池相关的有趣测试用例。通过该测试,帮助我们深入理解 JDK6、JDK7 和 JDK8+ 版本中字符串常量池的演变,以及 intern()
方法的关键变更。
相关概念
在深入代码分析之前,先了解几个关键概念:
-
方法区(Method Area):用于存储类信息、常量池、静态变量等,JDK6 及之前版本的方法区位于永久代(PermGen),JDK7+ 开始使用元空间(Metaspace)。
-
字符串常量池(String Constant Pool):用于存放字符串字面量,减少字符串对象重复创建带来的内存开销。
方法区 (Method Area) [JDK 1.8+为元空间] └── 运行时常量池 (Runtime Constant Pool) └── 字符串常量池 (String Constant Pool) [JDK 1.7之前在方法区,JDK 1.7+在堆中]
-
String::intern()
方法:- JDK6 及之前:如果字符串在常量池中不存在,会创建一个拷贝存入池中,并返回该池中字符串的引用。
- JDK7+:不再拷贝,而是直接存储堆中的引用,减少不必要的内存占用。
测试代码分析
public class RuntimeConstantPoolOOM {
public static void main