超越Java 8:紧凑型字符串

160 阅读6分钟

导言

根据一些调查,如JetBrains,Java的第8版目前是全世界开发人员使用最多的版本,尽管它是2014年发布的版本。

您正在阅读的是题为“超越Java 8”的系列文章中的第一篇,受我的书内容的启发。这些文章将引导读者一步一步地探索从版本9开始引入的最重要的特性。目的是让读者意识到从Java 8开始前进是多么重要,并解释最新版本的Java语言所提供的巨大优势。

在本文中,我们将讨论紧串,这是Java 9引入的一种机制,它是放弃Java 8并且升级到最新版本之一的最有效的理由之一。

扰流警报

这个String类是Java编程中使用最多的类。因此,问自己这个类型的对象有多高的效率是很重要的。好消息是,从Java 9开始,这些对象的性能明显优于以前的版本。此外,这一优势实际上是在不费吹灰之力的情况下获得的,也就是说,只要用JVM版本9(或更高版本)启动我们的程序就足够了,而无需对我们的代码采取任何预防措施。那么,让我们了解什么是紧凑型字符串,以及如何使用它们。

超越Java 8:紧凑型字符串

图1-src.zip文件在JDK版本8安装文件夹中的位置。

直到Java 8,一个数组焦耳用于存储组成字符串的字符。通过读取弦班级。要做到这一点,只需搜索String.java文件中的Src.zip文件位于JDK版本8的安装文件夹中。

该文件包含标准Java库的所有源文件。

因此,在解压缩之后,我们可以找到String.java类中的Java/LANG路径(实际上,String类属于java.lang(一揽子)。如果我们用任何编辑器打开这个文件,我们可以验证String类的声明如下(我们删除了一些注释和其他对我们的讨论不有用的元素):

超越Java 8:紧凑型字符串

因此,直到Java 8,价值字符数组意味着为字符串的每个字符分配16位(2字节)内存。

实际上,在大多数应用程序中,我们使用的字符只能存储在8位(1字节)。因此,为了在我们的程序中获得更高的速度和内存使用性能,在Java 9中实现了String类已被修改为由字节数组而不是char阵列。以下是声明的初始部分:String类在Java的第15版中,去掉一些不感兴趣的元素:

超越Java 8:紧凑型字符串

超越Java 8:紧凑型字符串

图2-src.zip文件在JDK版本15安装文件夹中的位置。

从JDK 9,Src.zip文件已移动到利布目录,并且包已经包含在表示模块的文件夹中。所以,String.java源现在位于Java.base/java/lang文件夹。事实上,Java.base是包含java.lang包裹。

但是,总是可以使用不太常见的字符,这些字符需要存储在16位(2字节)中。实际上,在String类,已经实现了一种基于编码器变量,它负责为每个字符分配正确的字节数。这个机制被称为紧串,和因为Java版本9是JVM默认使用的方法。没有任何程序更改,我们将使用字符串,因为我们一直使用它们。但是,Java应用程序的性能会更好。

我们真的要把一半的记忆用在字符串上吗?

虽然我们注意到今天String类支持byte数组而不是char数组与版本8一样,不幸的是,使用Java无法预先确定程序将使用多少内存。事实上,它是由垃圾收集器的复杂机制自动管理的,在每次执行时,我们的程序可以使用非常不同的内存。此外,在Java中,不可能精确地知道在任何给定的时间,有多少内存被用于某个对象,就像其他语言所能做到的那样。

基于Instrumentation接口的java.lang.文书包,可以近似于对象的大小,但这不适用于字符串,因为字符串是不可变的对象,在内存中以不同于其他项的方式分配。因此,即使紧凑型字符串机制似乎意味着节省内存,这也是不确定的,也是不可证明的。因此,让我们看看在代码示例中使用JDK版本9或更高版本有什么好处。

让我们考虑以下示例:

超越Java 8:紧凑型字符串

在这个类中,10万个字符串被实例化(其中包含前10万个数字)并进行连接。此外,还计算并打印了创建这些实例并将它们连接起来所需的毫秒。

让我们尝试使用JDK版本15.1 5次启动此应用程序,并分析输出:

超越Java 8:紧凑型字符串

我们可以观察到,每次启动时,应用程序的速度几乎是恒定的,大约为3.5秒。

因此,让我们尝试使用-XX:-CompactStrings选项,然后尝试运行相同的应用程序5次,然后分析结果:

超越Java 8:紧凑型字符串

同样,速度方面的性能几乎是恒定的,但比我们使用紧凑型字符串时差得多。事实上,这个没有紧凑型字符串的应用程序的平均执行速度大约是8.5秒,而当我们使用压缩字符串时,平均只有3.5秒。一个重要的优势已经为我们节省了近60%的时间。

如果我们甚至用最新版本的Java 8(JDK 1.8.0_261)直接重新编译和重新启动该程序,那么这些优点就更明显了:

超越Java 8:紧凑型字符串

这一次性能的下降更加明显:使用JDK 15和紧凑型字符串,应用程序的性能几乎要好10倍!当然,这并不意味着所有程序都会有如此大的改进,因为我们的示例完全基于字符串的分配和连接。

关于内存使用的节省,尽管我们已经说过,但这是不可能的,因为垃圾收集器根据当前的情况执行一项复杂的工作。

结论

在本文中,我们已经看到了从Java 8开始前进的第一个有效理由,从版本9开始引入的紧凑型字符串使我们的程序在使用字符串时效率更高。因为弦类是Java程序中使用最多的类,我们可以得出结论,仅仅使用版本大于8的JDK就可以保证我们的应用程序更快的执行速度。我们还发现,与JDK 8的最新版本相比,不使用紧凑字符串的JDK 15仍然可以保证更高的性能。

最后

小伙伴们如果觉得我写得不错请点赞加关注!!更多Java进阶学习资料、2022大厂面试真题,完整资料已经给大家打包完毕,需要资料的小伙伴关注博主,私信“学习”或者“面经”即可获得免费资料

超越Java 8:紧凑型字符串