你好! 我们在现在的第九组
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; 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
命令来禁用此功能。
与往常一样,我们在这里等待您的评论和问题,并邀请您参加
公开课程 。