1 :String literal
String str = "Elroy";
在这里,JVM 检查字符串常量池。如果字符串不存在,则创建一个新的字符串实例并将其放置在池中。如果字符串存在,则不会创建新对象。相反,它将返回对同一实例的引用。存储这些字符串实例的缓存称为字符串常量池或字符串池。在 Java 的早期版本中,直到 JDK 6 字符串池位于 PermGen(永久代)空间内。但是在 JDK 7 中,它被移到了主堆区域。
2: 使用new关键字
String s = new String (“Elroy”);
字符串也可以使用new运算符进行声明,即动态分配。如果 String 是动态分配的,它们会在堆中分配一个新的内存位置。该字符串不会被添加到字符串常量池中。
最好使用第一种方法,因为它允许 JVM 优化内存分配。
为什么字符串池从 永久代移动到正常的堆区域?
永久代空间有限,默认大小仅为 64 MB。在永久代 空间中创建和存储太多字符串对象是一个问题。这就是字符串池被移到更大的堆区域的原因。为了使 Java 内存效率更高,使用了字符串字面量的概念。通过使用 'new' 关键字,即使字符串池中存在相同的字符串对象,JVM 也会在普通堆区域中创建一个新的字符串对象。