常量池
字符串池
在JVM中,为了减少相同的字符串的重复创建,为了达到节省内存的目的。会单独开辟一块内存,用于保存字符串常量,这个内存区域被叫做字符串常量池。
当代码中出现双引号形式(字面量)创建字符串对象时,JVM 会先对这个字符串进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回;否则,创建新的字符串对象,然后将这个引用放入字符串常量池,并返回该引用。
这种机制,就是字符串驻留或池化。
字符串常量池的位置:
JDK 7 以前常量池存放在永久代中,JDK 7 中将字符串常量池移动到了堆内存中
永久代(Permanent Generation)是 Java 虚拟机(JVM)中的一部分,用于存放类的元数据,例如类的名称、方法信息、字段信息等。它是堆内存的一部分,但与堆的新生代和老年代不同,它主要用于存放不会被垃圾回收器回收的数据。在旧版的 Java 虚拟机中,永久代通常被用来存放 JVM 加载的类信息。
JDK 8 中使用元空间替代了永久代,字符串常量仍在堆中存储
(感兴趣可以查看https://blog.csdn.net/qq_41813208/article/details/110849158)
Class常量池
Class文件:由字节码组成
Class常量池可以理解为Class文件中的资源仓库,存放了编译器生成的各种字面量和符号引用
用处:Java代码编译时没有链接这一步,所以Class文件都是割裂的,当虚拟机运行时需要从常量池中获得对应的符号引用,再在类创建或运行时解析、翻译到具体的内存地址中
运行时常量池
运行时常量池( Runtime Constant Pool)是每一个类或接口的常量池( Constant_Pool)的运行时表示形式。
它包括了若干种不同的常量:从编译期可知的数值字面量到必须运行期解析后才能获得的方法或字段引用。运行时常量池扮演了类似传统语言中符号表( SymbolTable)的角色,不过它存储数据范围比通常意义上的符号表要更为广泛。
intern可以在运行期将字符串内容放置到字符串常量池
intern的功能很简单:
在每次赋值的时候使用 String 的 intern 方法,如果常量池中有相同值,就会重复使用该对象,返回对象引用。