Java 9 – 精简字符串改进 [JEP 254]
直到 Java 8,Java 中的字符串内部都由char[]
表示。 每个char
都以 2 个字节存储在内存中。 oracle 的 JDK 开发人员分析了许多客户端的应用程序堆转储,他们注意到大多数字符串只能使用 Latin-1 字符集表示。 拉丁 1 个字符可以存储在一个字节中,比char
数据类型存储少 50%(1 个字节)。
因此,JDK 开发人员将String
类的内部存储从char[]
缺省设置为byte[]
。 通常,这导致节省了堆内存的大量空间,因为字符串对象实际上占据了堆内存的很大一部分。(来源)
您可以使用java
命令的-XX:-CompactStrings
参数来控制应用程序中此特性的使用。
Java 9 之前的字符串类
在 Java 9 之前,字符串数据存储为char
数组。 每个字符需要 16 位。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
//The value is used for character storage.
private final char value[];
}
Java 9 之后的字符串类
从 Java 9 开始,现在使用字节数组以及用于编码引用的标志字段在内部表示字符串。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
@Stable
private final byte[] value;
/**
* The identifier of the encoding used to encode the bytes in
* {@code value}. The supported values in this implementation are
*
* LATIN1
* UTF16
*
* @implNote This field is trusted by the VM, and is a subject to
* constant folding if String instance is constant. Overwriting this
* field after construction will cause problems.
*/
private final byte coder;
}
java
命令参考
众所周知,java
命令用于启动 Java 应用程序。 它可以具有许多参数来定制应用程序运行时。 下面是一个这样的命令:
-XX:-CompactStrings
禁用精简字符串特性。 默认情况下,启用此选项。 启用此选项后,内部仅包含单字节字符的 Java 字符串将使用 ISO-8859-1/Latin-1 编码在内部表示并存储为每个字符的单字节字符串。 这将只包含单字节字符的字符串减少了 50% 的空间。 对于包含至少一个多字节字符的 Java 字符串:这些字符串使用 UTF-16 编码表示并存储为每个字符 2 个字节。 禁用精简字符串特性将强制使用 UTF-16 编码作为所有 Java 字符串的内部表示。
禁用精简字符串可能有益的情况包括:
- 当知道应用程序将大量分配多字节字符字符串时
- 在从 Java SE 8 迁移到 Java SE 9 的过程中观察到性能下降的意外事件中,分析表明精简字符串引入了回归。
在这两种情况下,禁用精简字符串都是有意义的。
这纯粹是实现更改,不更改现有的公共接口。
将我的问题放在评论部分。
学习愉快!