在此Oracle页面Java HotSpot VM Options上,它将-XX:+UseCompressedStrings
列为可用并默认启用。但是在Java 6更新29中,默认情况下它处于关闭状态,并且在Java 7 update 2中它会报告警告
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option UseCompressedStrings; support was removed in 7.0
有没有人知道删除此选项背后的想法?
sorting lines of an enormous file.txt in java
使用-mx2g
,此示例在选项打开时耗时4.541秒,在Java 6更新29中耗尽5.206秒。很难看出它会影响性能。
注意:Java 7更新2需要2.0 G,而没有压缩字符串的Java 6更新29需要1.8 GB,压缩字符串只需要1.0 GB。
答案 0 :(得分:40)
最初,添加了此选项以改善SPECjBB性能。增益是由于处理器和DRAM之间的内存带宽需求减少。在字节[]中加载和存储字节消耗的带宽是char []中的字符的1/2。
然而,这是有代价的。代码必须确定内部数组是byte []还是char []。这需要CPU时间,如果工作负载不是内存带宽受限,则可能导致性能下降。由于增加了复杂性,还有代码维护价格。
由于没有足够的类似生产的工作负载显示出显着的收益(除了SPECjBB),该选项已被删除。
还有另一个角度。该选项可减少堆使用量。对于适用的字符串,它会将这些字符串的内存使用量减少1/2。在删除选项时不考虑该角度。对于内存容量约束的工作负载(即必须以有限的堆空间运行并且GC需要花费大量时间),此选项可证明是有用的。
如果有足够的内存容量约束类似生产的工作负载可以证明该选项的包含,那么可能该选项将被带回。
编辑2013年3月20日:平均服务器堆转储占用Strings上25%的空间。大多数字符串都是可压缩的。如果重新引入该选项,则可以节省一半的空间(例如~12%)!
编辑3/10/2016:类似于压缩字符串的功能将在JDK 9 JEP 254中回归。
答案 1 :(得分:14)
只是为那些感兴趣的人添加...
java.lang.CharSequence接口(java.lang.String
实现)允许比UTF-16更紧凑的字符串表示。
应该编写操作大量字符串的应用程序来接受CharSequence
,以便它们可以与java.lang.String
,或更紧凑的表示形式一起使用。
8位(UTF-8),甚至5,6或7位编码,甚至压缩的字符串都可以表示为CharSequence
。
CharSequence
s也可以更有效地进行操作 - 子序列可以定义为原始内容的视图(指针),而不是复制。
例如在concurrent-trees中,一个莎士比亚戏剧的十个后缀树,requires 2GB of RAM使用基于CharSequence
的节点,would require 249GB of RAM如果使用char []或String-基于节点。
答案 2 :(得分:13)
由于有投票,我认为我没有遗漏一些明显的东西,所以我把它记录为一个错误(至少在文档中有遗漏)
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7129417
(应该在几天内可见)
答案 3 :(得分:6)
Java 9在我的机器上执行sorting lines of an enormous file.txt in java的速度是Java 6的两倍,并且只需要1G的内存,因为它默认启用了-XX:+CompactStrings
。此外,在Java 6中,压缩字符串仅适用于7位ASCII字符,而在Java 9中,它支持Latin1(ISO-8859-1)。但是charAt(idx)
之类的某些操作可能会略微变慢。通过新设计,他们还可以支持其他编码。
我在The Java Specialists' Newsletter上写了一篇关于此事的简报。
答案 4 :(得分:4)
在OpenJDK 7(1.7.0_147-icedtea,Ubuntu 11.10)中,JVM只是失败了
当无法识别的VM选项'UseCompressedStrings'
JAVA_OPTS
(或命令行)包含-XX:+UseCompressedStrings
时。
似乎Oracle确实删除了该选项。