[评论]为什么不能使用Java 7?

Java 7刚刚发布没两天,但来自Lucene和Solr 社区的某些人立即报料了一些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崩溃并报严重错误,信息如下:

代码:

  1. # A fatal error has been detected by the Java Runtime Environment:  
  2. #  
  3. #  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000026536dapid=5432, t  
  4. id=6568 
  5. #  
  6. # JRE version: 7.0-b135  
  7. # Java VM: Java HotSpot(TM) 64-Bit Server VM (21.0-b05 mixed mode windows-amd64  
  8. compressed oops)  
  9. # Problematic frame:  
  10. # 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似乎也正在准备下一个补丁版本,但对一些高级用户来说,这些都不是问题,因为源码是开放的,你可以做你想做的。

原文出自:eisele.net

译文出自:oschina

posted @ 2011-08-03 16:29  张长胜  阅读(244)  评论(0编辑  收藏  举报