## 方法区 ![](https://img.kancloud.cn/87/84/878449a216837583ee6c26a543971363_936x588.png) ### 运行时常量池 ## 字符串在JVM中如何存放? 方法区是一个逻辑规范,运行时常量池属于方法区。但是在物理存储上存在争议: ### 版本1:常量池在堆中(主流) 字符串对象在JVM中可能有两个存放的位置:`字符串常量池`或`堆内存`。 1. 使用常量字符串初始化的字符串对象,它的值存放在字符串常量池中; 2. 使用字符串构造方法`new String()`创建的字符串对象,它的值存放在堆内存中; String提供了一个API, java.lang.String.intern(),这个API可以手动将一个字符串对象的值转移到字符串常量池中。 在1.7之前,字符串常量池是在PermGen区域,这个区域的大小是固定的——不能在运行时根据需要扩大,也不能被垃圾收集器回收,因此如果程序中有太多的字符串调用了intern方法的话,就可能造成OOM。 在1.7以后,字符串常量池移到了堆内存中,并且可以被垃圾收集器回收,这个改动降低了字符串常量池OOM的风险。 > ✋我有问题:这块内容存在一定的争议。 ### 版本2:常量池移到元空间,使用直接内存 JDK1.8中方法区实现改成了元空间,字符串常量池直接放到了直接内存,但是运行时常量池物理上还是在堆区,虽然物理存放的地方变了,逻辑上看元空间、运行时常量池还是属于方法区。 [查看出处](https://www.zhihu.com/question/300075241/answer/519570351)