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

Pet*_*rey 58 java performance jvm java-7

在此页面甲骨文的Java HotSpot虚拟机的选项,它会列出-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
Run Code Online (Sandbox Code Playgroud)

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


在java中对巨大的file.txt进行排序

有了-mx2g这个例子,选项打开了4.541秒,在Java 6更新29中关闭了5.206秒.很难看出它会影响性能.

注意:Java 7更新2需要2.0 G,而没有压缩字符串的Java 6更新29需要1.8 GB,压缩字符串只需要1.0 GB.

Nat*_*han 41

最初,添加此选项是为了改善SPECjBB性能.增益是由于处理器和DRAM之间的内存带宽需求减少.在字节[]中加载和存储字节消耗带宽的1/2与char []中的字符相比.

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

由于没有足够的类似生产的工作负载显示出显着的收益(除了SPECjBB),该选项已被删除.

还有另一个角度.该选项可减少堆使用量.对于适用的字符串,它会将这些字符串的内存使用量减少1/2.在删除选项时不考虑该角度.对于受内存容量限制的工作负载(即必须以有限的堆空间运行而GC需要花费大量时间),此选项可证明是有用的.

如果可以找到足够的内存容量限制类似生产的工作负载来证明该选项的包含,那么可能会返回该选项.

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

编辑3/10/2016:类似于压缩字符串的功能将在JDK 9 JEP 254中重新出现.

  • 它不应该付出代价.Java应该能够提供可用于从已知仅包含字节的源构建字符串的api.相反,它选择不信任程序员并自己验证一切.类似地,java可以提供一个api,允许从现有数组中实例化String; 相反,它完全不信任所有程序员和力量总是复制数组. (4认同)
  • @srparish:我很确定允许你描述的内容会破坏JVM的安全性/接受你的数组作为String组件会使String变为可变,并且使用String作为类名,你可以在JVM中做任何你想做的事情.因此,非复制的公共构造函数`String(char [])`必须由`SecurityManager`保护,这可能会使它们比复制版本慢. (3认同)
  • 我希望将其添加回来.它实际上对于加速处理最小字符集的文本解析应用程序非常有用,并且如果您将数据集保留在内存中,肯定会减少堆使用量. (2认同)

npg*_*all 14

只是为了那些感兴趣的人......

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

其操纵大量字符串的应用程序,可能应该被写入接受CharSequence,这样,他们将一起工作java.lang.String,或者更紧凑的表示.

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

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

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


Pet*_*rey 13

由于有投票,我认为我没有遗漏一些明显的东西所以我把它记录为一个错误(至少在文档中的遗漏)

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7129417

(应该在几天内可见)

  • @bestsss:我想知道有什么困难,而不是每个数字原语都有一个数组类型,有一个统一的原始数组实例类型,可以转换为任何其他,以及JVM定义的静态最终变量表明这些数组是否会表现为big-endian或little-endian?通过一次抓取两件或四件事可以加速多种操作. (2认同)
  • @supercat,请记住,没有人会停止JIT来优化生成的代码并减少负载(即使它们在点击L1时非常便宜).即使是现在,JIT也可以使用内部函数(以及x86上的SSE,它比64位长更有效)来处理String,它在java级别上是不可见的.不可否认,我已经有一段时间没有关注JIT了.实际上从java1.7开始,hashCode primary使用murmur32作为哈希函数,并且原来的hashCode使用不多.代码在任何地方使用32位操作,JIT也应该能够优化获取. (2认同)

小智 6

Java 9 在我的机器上执行Java中巨大的file.txt排序行的速度是Java 6的两倍,并且-XX:+CompactStrings默认情况下也只需要1G的内存.此外,在Java 6中,压缩字符串仅适用于7位ASCII字符,而在Java 9中,它支持Latin1(ISO-8859-1).但是有些操作charAt(idx)可能稍微慢一点.通过新设计,他们还可以支持其他编码.

我在The Java Specialists's Newsletter上写了一篇关于此的新闻通讯.