别用 Java 7 ? 你是在开玩笑吗?

来源:oschina 作者:oschina
  

Java 7 刚刚发布没两天,但来自 LuceneSolr 社区的某些人立即报料了一些 Java 7 中的严重bug。甚至 Apache Lucene 项目管理委员会成员 Uwe Schindler 发布了暂时不要使用 Java 7 的警告信息。 那么到底 Java 7 是有什么问题,为什么我们等了 5 年的 Java 7 现在却不能使用呢?让我们来看看实际的情况。

 

这个问题跟 Java 7 无关,而是跟 JVM 有关

首先这个问题是跟 HotSpot JVM 有关,而不是 Java 7 语言本身的问题。此次发布的 GA 版本包含三个bug:7070134, 70447387068051 ,这三个bug直接导致 JVM 崩溃或者进行错误的计算。

 

Hotspot 是因为 PorterStemmer 的 sigsegv 而崩溃的

第一个问题(7070134) 是关于错误的编译器对循环的优化,该特性在 Hotspot JVM 中是默认启用的,你可以通过 -XX:-UseLoopPredicate 参数来关闭这个特性。如果你想了解关于这个问题的详情,请看 Stemmer.java ,编译并允许这个类你将会重现 JVM 崩溃并报严重错误,信息如下:

# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000026536da, pid=5432, t
id=6568
#
# JRE version: 7.0-b135
# Java VM: Java HotSpot(TM) 64-Bit Server VM (21.0-b05 mixed mode windows-amd64
compressed oops)
# Problematic frame:
# J  Stemmer.step4()V

这个错误直接在代码执行过程中发生,在 JDK 1.6 是体验不到的。而最近 Lucene 做了一些更灵活的基于 PulsingCodec 算法的索引机制,而这个机制相当大的程度上会导致上述的错误。

 

循环展开优化会导致不正确的结果

第二个bug (7044738) 是“错误的计算”,这个错误极为罕见的发生在 OSR (On-Stack Replacement) 编译嵌套循环上,控制流退出且对应的内存没有被考虑到,这直接导致重复的克隆结果,想了解编译细节请看 older overview (PDF)

一个最简单的解决办法就是使用 -XX:LoopUnrollLimit=1 参数来避免这个问题。 

 

Clone loop predicate during loop unswitch

第三个bug(7068051) 跟一些老的 feature request 相关,由于一些无效的 JVM 统计导致使用循环优化后的 JVM 崩溃。

结论

 根据这些bug的情况,只有在你大量的使用这些优化方法,那么你才可能已经受 Java 7 中存在的问题所影响。一般情况下是不受影响的。事实上 Java 6 的用户使用了某些优化选项也会存在问题,但因为这些优化选项在 Java 7 中是默认启用的才导致这个问题影响那么大,例如 (-XX:+OptimizeStringConcat or -XX:+AggressiveOpts) ,由于这些问题在 Java 7 发布的前 5 天才被发现,因此 Oracle 来不及解决这些bug,目前 Oracle 似乎也正在准备下一个补丁版本,但对一些高级用户来说,这些都不是问题,因为源码是开放的,你可以做你想做的。

 

本文译自 http://blog.eisele.net/2011/07/dont-use-java-7-are-you-kidding-me.html

(如有翻译不妥的地方,请多包涵)


时间:2011-08-03 08:54 来源:oschina 作者:oschina 原文链接

好文,顶一下
(2)
100%
文章真差,踩一下
(0)
0%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量