interview
java-basics
为什么 JDK 9 中将 String 的 char 数组改为 byte 数组

Java 基础面试题, 为什么 JDK 9 中将 String 的 char 数组改为 byte 数组?

Java 基础面试题, 为什么 JDK 9 中将 String 的 char 数组改为 byte 数组?

QA

Step 1

Q:: 为什么 JDK 9 中将 String 的 char 数组改为 byte 数组?

A:: JDK 9 中对 String 类进行了优化,将底层的 char[] 数组替换为 byte[] 数组。这种变更称为 'Compact Strings',其主要目的是节省内存。之前的 char[] 数组在内存中每个字符都占用两个字节(16 位),这在处理大量 ASCII 字符的场景下会造成不必要的内存浪费。通过改为 byte[] 数组,JVM 可以根据字符串内容自动选择使用 Latin-1 编码(1 字节)或 UTF-16 编码(2 字节),从而节省内存空间并提高效率。这种优化特别在处理大量短字符串时能够显著减少内存占用。

Step 2

Q:: JDK 9 中的 Compact Strings 是如何实现的?

A:: Compact Strings 的实现是通过 String 类的两个内部字段来管理的:一个是 byte[] 数组来存储实际的字符串数据,另一个是 coder 字段来指示使用的编码方式(LATIN1 或 UTF16)。当字符串包含的都是 ISO-8859-1 范围内的字符时,使用 LATIN1 编码(1 字节),否则使用 UTF16 编码(2 字节)。这种设计使得在大多数情况下,字符串占用的内存减少了近一半。

Step 3

Q:: Compact Strings 对性能有什么影响?

A:: 总体而言,Compact Strings 的引入不仅减少了内存使用,还可能提升了一些场景下的性能,特别是内存的缓存命中率提高了。然而,在某些极端情况下,可能会因为增加的编码检查开销而略微降低性能。实际的性能提升或者下降取决于应用的具体场景,比如字符串的长度、内容以及操作的复杂度。

用途

这个内容被问及的原因主要是因为它涉及到 Java 平台的内存优化和性能提升,这是 Java 开发中非常重要的一部分。特别是对于那些需要处理大量字符串的应用(例如日志系统、文本处理器、Web 服务等),理解底层的内存管理和字符串处理机制对优化程序的性能非常关键。在生产环境中,这种优化能够直接影响应用的内存占用和响应速度,特别是在资源受限或者需要高效处理海量数据的场景下,Compact Strings 机制会变得非常有用。\n

相关问题

🦆
什么是 String Pool,如何在 JDK 9 中运作?

String Pool 是 Java 中一种用于节省内存的机制,它存储了在 JVM 中重复出现的字符串字面量。当一个字符串被创建时,如果它已经存在于 String Pool 中,JVM 将返回该池中的引用,而不会创建一个新的字符串对象。在 JDK 9 中,String Pool 中的字符串也受益于 Compact Strings 的优化,即使是池中的字符串也将以 byte[] 的形式存储,进一步减少内存使用。

🦆
Java 中的 String 是不可变的,为什么要设计成不可变?

String 设计成不可变主要有几个原因:首先,不可变对象是线程安全的,可以在多个线程中安全地共享;其次,不可变对象在哈希表中作为键使用时性能更好,因为它们的哈希值是固定的;最后,不可变性也有助于减少内存泄漏的风险,尤其是在大量使用字符串的情况下。

🦆
在 JDK 9 中,如何使用 Compact Strings 的优势?

在 JDK 9 及以后版本中,Compact Strings 是自动启用的,开发者无需额外操作即可受益于这一优化。然而,在编写代码时,可以通过确保尽量使用简单的 ASCII 字符(例如小写英文字母)来最大化内存节省效果。此外,避免频繁拼接字符串(使用 StringBuilder 或者 StringBuffer 代替)也有助于保持性能优势。