Java 9中的紧凑字符串

你好! 我们在现在的第九组Java Developer组 (计划中的第十组,突然在12月31日)中打开了下一组并为您准备了有趣的材料和公开课程

所以走吧

是否要减少Java应用程序使用的内存量? 了解如何使用Java 9中可用的紧凑字符串来提高性能。

作为Java SE 9的一部分,JVM(准确地说是Oracle HotSpot)引入的性能改进之一是紧凑的字符串。 他们的任务是减少String对象的大小,从而减少应用程序消耗的内存总量(占用空间)。 结果,这可以减少收集垃圾所花费的时间。



该函数基于以下观察结果:由于大多数应用程序仅使用Latin-1字符,因此许多String对象不需要2个字节即可对每个字符进行编码。 因此,代替此:

/**       */ private final char value[]; 

java.lang.String现在有了这个:

 private final byte[] value; /** *        * {@code value}.      : * * LATIN1 * UTF16 * * @implNote     .    * “”,   String - .   *      . */ private final byte coder; 

换句话说,此函数将char数组(每个元素使用2个字节)中的值替换为带有附加字节的字节数组以确定编码(Latin-1或UTF-16)。 这意味着在大多数仅使用Latin-1字符的应用程序中,将仅使用一半的堆。 用户不会注意到这些差异,但是相关的API(例如StringBuilder )将自动利用这一点。

为了显示String对象大小的变化,我将使用Java Object Layout,这是一个简单的实用工具,用于可视化堆上对象的结构。 从这个角度来看,我们对数组的占用空间(存储在上面的value变量中)感兴趣,而不仅仅是引用(字节数组引用,像字符数组引用一样,使用4个字节)。 下面的代码使用JOL GraphLayout显示信息:

 public class JOLSample { public static void main(String[] args) { System.out.println(GraphLayout.parseInstance("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").toFootprint()); } } )toFootprint()); public class JOLSample { public static void main(String[] args) { System.out.println(GraphLayout.parseInstance("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").toFootprint()); } } 

在Java 8中然后在Java 9中运行上面的代码显示了不同之处:

 $java -version java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode) $java -cp lib\jol-cli-0.9-full.jar;. test.JOLSample java.lang.String@4554617cd footprint: COUNT AVG SUM DESCRIPTION 1 432 432 [C 1 24 24 java.lang.String 2 456 (total) ... $java -version java version "9" Java(TM) SE Runtime Environment (build 9+181) Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode) $java -cp lib\jol-cli-0.9-full.jar;. test.JOLSample java.lang.String@73035e27d footprint: COUNT AVG SUM DESCRIPTION 1 224 224 [B 1 24 24 java.lang.String 2 248 (total) 

忽略java.lang.String内部组件(标头和链接)的24字节大小,由于其紧凑性,我们发现该大小几乎减少了一半。
如果我们用UTF-16字符替换另一行(例如\ u0780),然后重新启动上面的代码,则Java 8和Java 9将显示相同的占用空间,因为将不再使用紧凑性。

您可以通过将-XX:-CompactStrings传递给java命令来禁用此功能。

与往常一样,我们在这里等待您的评论和问题,并邀请您参加公开课程

Source: https://habr.com/ru/post/zh-CN426621/


All Articles