是否支持在 HotSpot JVM 中删除压缩字符串?

2022-08-31 16:42:24

在此 Oracle 页面上,Java HotSpot VM Options,它列出默认为可用且处于打开状态。但是,在 Java 6 update 29 中,默认情况下它是关闭的,而在 Java 7 update 2 中,它会报告警告-XX:+UseCompressedStrings

Java HotSpot(TM) 64-Bit Server VM warning: ignoring option UseCompressedStrings; support was removed in 7.0

有谁知道删除此选项背后的想法?


对一个巨大的文件的行进行排序.txt java

在 Java 6 更新 29 中,此示例在打开选项的情况下花费了 4.541 秒,关闭该选项时花费了 5.206 秒。很难看出它会影响性能。-mx2g

注意:Java 7 update 2 需要 2.0 G,而不带压缩字符串的 Java 6 update 29 需要 1.8 GB,而使用压缩字符串只需要 1.0 GB。


答案 1

最初,添加此选项是为了提高 SPECjBB 性能。增益是由于处理器和 DRAM 之间的内存带宽要求降低。在 byte[] 中加载和存储字节消耗的带宽是 char[] 中的字符的 1/2。

但是,这是有代价的。代码必须确定内部数组是 byte[] 还是 char[]。这需要 CPU 时间,如果工作负载不受内存带宽限制,则可能导致性能下降。由于增加了复杂性,还有代码维护价格。

由于没有足够的类似生产的工作负载显示出显著的收益(SPECjBB 除外),因此删除了该选项。

这还有另一个角度。该选项可减少堆使用量。对于适用的字符串,它将这些字符串的内存使用量减少了 1/2。在选项删除时未考虑此角度。对于内存容量受限的工作负载(即必须在有限的堆空间下运行,并且 GC 需要花费大量时间),此选项非常有用。

如果可以找到足够的内存容量受限的类似生产工作负载来证明包含该选项的合理性,那么该选项可能会被带回来。

编辑3/20/2013:平均服务器堆转储使用字符串上 25% 的空间。大多数字符串都是可压缩的。如果重新引入该选项,它可以节省一半的空间(例如~12%)!

编辑3/10/2016:类似于压缩字符串的功能在 JDK 9 JEP 254 中回归。


答案 2

只是为了补充,对于那些感兴趣的人...

java.lang.CharSequence接口(实现)允许比UTF-16更紧凑的字符串表示。java.lang.String

操作大量字符串的应用程序可能应该编写为接受 ,以便它们可以使用 或更紧凑的表示形式CharSequencejava.lang.String

8 位 (UTF-8),甚至 5、6 或 7 位编码,甚至压缩字符串都可以表示为 .CharSequence

CharSequences也可以更有效地操作 - 子序列可以定义为例如原始内容的视图(指针),而不是复制。

例如,在并发树中,莎士比亚戏剧的十个后缀树使用基于节点需要2GB的RAM,如果使用char[]或基于字符串的节点,则需要249GB的RAMCharSequence


推荐