Java 中的 String
类是编程中使用最频繁的类之一,它用于表示字符序列。随着 Java Development Kit (JDK) 的不断迭代,String
类的底层设计和优化也在不断发展,以提高性能和内存使用效率。
在 JDK 6 中,String
类的常量池位于永久代(方法区)中。此时,常量池存储的是对象本身。这意味着,所有的字符串字面量都会在常量池中创建一个实例,如果使用 new
关键字创建字符串,也会在堆内存中创建一个新的 String
对象,并且常量池中也会有一个对应的实例。
JDK 7 引入了一项重要的变化,将常量池从永久代移到了堆内存中。此时,常量池存储的是对象的引用。这意味着,字符串字面量和通过 new
创建的 String
对象都会在堆内存中,而常量池中存储的是它们的引用。这一变化使得字符串的存储和管理更加灵活。
JDK 8 进一步优化了 String
类,引入了元空间(Metaspace)来取代永久代。元空间使用的是本地内存,而不是虚拟机内存,这有助于减少内存溢出的风险。此外,JDK 8 还对字符串的创建和 intern()
方法的行为进行了优化。例如,在 JDK 8 中,通过 new String("text").intern()
创建的字符串和直接使用字面量 "text" 创建的字符串,可能会指向同一个对象,这在 JDK 7 中是不可能的。
JDK 9 对 String
类进行了重大的底层优化。在 JDK 9 中,String
类不再使用 char
数组来存储字符串数据,而是改用 byte
数组。这一改变基于一个观察:大多数字符串只包含 Latin-1 字符集的字符,这些字符可以用一个字节来表示。通过使用一个字节的编码格式,JDK 9 减少了 String
对象的内存占用。如果字符串包含非 Latin-1 字符,JDK 会使用 UTF-16 编码,这与之前的版本相同。
此外,JDK 9 还引入了一个 coder
字段,用于标识字符串的编码格式,以及一个 COMPACT_STRINGS
属性,用于控制是否开启字符串的紧凑存储功能。默认情况下,这个功能是开启的,可以通过 -XX:-CompactStrings
参数来关闭。
随着 JDK 版本的迭代,String
类的底层设计和优化不断改进,以适应不同的使用场景和提高性能。从 JDK 6 的永久代常量池,到 JDK 7 的堆内存常量池,再到 JDK 8 的元空间和 intern()
方法的优化,以及 JDK 9 的内存占用优化,Java 的 String
类一直在进化。这些改进不仅提高了性能,还减少了内存占用,使得 Java 程序更加高效和稳定。