常量池分为两个地方:运行时常量池 和 字符串常量池 运行时常量池: 字节码文件里面有个constant pool,存储着编译时生成的常量信息,在运行的时候,这些信息会被放在方法区中的运行时常量池中。 字符串常量池:存储一些字符串常量,位于堆区。 作用:避免重复创建相同的对象,节省内存并提高效率,
延伸→字符串常量池能否被垃圾回收?大量不同字符串不断intern()会导致内存溢出吗?
-
在Java 6之前,字符串常量池位于永久代(PermGen),由于永久代的垃圾回收效果不佳,如果字符串常量池中含有大量的字符串,很容易造成永久代溢出。
-
从Java 7开始,字符串常量池被挪到了堆中,堆空间一般比较大,且堆空间的回收效率较高,因此内存溢出的情况大大减少。
-
在Java 8中,字符串常量池仍然位于堆中,并且使用了元空间(Metaspace)代替永久代。元空间的内存大小取决于本地内存大小,这意味着字符串常量池的容量不再受限于JVM的固定内存大小,从而减少了内存溢出的风险
因此在java6之前,不断intern()不同字符串很容易就会造成内存溢出,java7以及java8之后这个情况就改善很多了。