显然Java7有一些关于循环优化的讨厌错误:Google search。
从报告和错误描述中我发现很难判断这个错误的重要性(除非你使用Solr或Lucene)。
我想知道的事情:
注意:我无法让我的程序用户使用-XX:-UseLoopPredicate
来避免此问题。
答案 0 :(得分:79)
任何热点错误的问题是,你需要达到编译门槛(例如10000)才能得到你:所以如果你的单元测试是“微不足道的”,你可能不会发现它。
例如,我们在lucene中发现了不正确的结果问题,因为此特定测试会创建20,000个文档索引。
在我们的测试中,我们随机化不同的接口(例如,不同的Directory实现)和索引参数等,并且测试仅在1%的时间内失败,当然它随后可以使用相同的随机种子重现。我们还对测试创建的每个索引运行checkindex,它会进行一些健全性测试以确保索引没有损坏。
对于我们发现的测试,如果您有特定的配置:例如为该字段存储的RAMDirectory + PulsingCodec +有效负载,然后在它达到编译阈值之后,对过帐的枚举循环返回不正确的计算,在这种情况下,一个术语的返回文档数量!=为该术语存储的docFreq。
我们有很多压力测试,重要的是要注意这个测试中的正常断言实际上是通过的,它的最后检查索引部分失败了。
这个问题的一大问题是,lucene的增量索引从根本上通过将多个段合并为一个来实现:因此,如果这些枚举计算出无效数据,则这些无效数据将存储到新的合并索引:又名腐败。
我会说这个错误比我们遇到的先前循环优化器热点错误(例如符号翻转的东西,https://issues.apache.org/jira/browse/LUCENE-2975)更加狡猾。在那种情况下,我们得到了古怪的负面文档增量,这使得它很容易捕获。我们也只需要手动展开一种方法来躲避它。另一方面,我们最初的唯一“测试”是一个巨大的10GB索引http://www.pangaea.de/,所以将它缩小到这个bug是很痛苦的。
在这种情况下,我花了很多时间(例如上周的每个晚上)试图手动展开/内联各种各样的东西,尝试创建一些解决方法,以便我们可以躲避错误,并且不会有腐败索引的可能性创建。我可以躲避一些案件,但还有更多案件我不能......而且我确信如果我们能够在测试中触发这些东西,那么还有更多的案例......
答案 1 :(得分:8)
重现错误的简单方法。打开eclipse(在我的情况下是Indigo),然后转到帮助/搜索。输入一个搜索字符串,你会发现eclipse崩溃了。看看日志。
# Problematic frame:
# J org.apache.lucene.analysis.PorterStemmer.stem([CII)Z
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
#
--------------- T H R E A D ---------------
Current thread (0x0000000007b79000): JavaThread "Worker-46" [_thread_in_Java, id=264, stack(0x000000000f380000,0x000000000f480000)]
siginfo: ExceptionCode=0xc0000005, reading address 0x00000002f62bd80e
Registers:
答案 2 :(得分:4)
问题仍然存在于2012年12月2日 在Oracle JDK中 java -version java版“1.7.0_09” Java(TM)SE运行时环境(版本1.7.0_09-b05) Java HotSpot(TM)64位服务器VM(内置23.5-b02,混合模式) 和openjdk java版“1.7.0_09-icedtea” OpenJDK运行时环境(fedora-2.3.3.fc17.1-x86_64) OpenJDK 64位服务器VM(版本23.2-b09,混合模式)
奇怪的是,任何一个人 -XX:-UseLoopPredicate或-XX:LoopUnrollLimit = 1 选项可防止错误发生, 但是当一起使用时 - JDK失败了 见例如 https://bugzilla.redhat.com/show_bug.cgi?id=849279
答案 3 :(得分:1)
两年后,我相信这个错误(或其变体)仍然存在于OSX的1.7.0_25-b15中。
通过非常痛苦的试验和错误,我已经确定使用带有Solr 3.6.2的Java 1.7和自动提交<maxTime>30000</maxTime>
似乎会导致索引损坏。如果我切换到Java 1.6,它似乎只发生w / 1.7和maxTime
30000,我没有问题。如果我将maxTime
降低到3000,我没有问题。
JVM不会崩溃,但它会导致RSolr死于Ruby中的以下堆栈跟踪: https://gist.github.com/armhold/6354416。它在保存了几百条记录后可靠地完成了这项工作。
鉴于这里涉及的层数很多(Ruby,Sunspot,Rsolr等),我不确定我是否可以将其归结为明确证明JVM错误的东西,但确实感觉就像这里发生的那样。 FWIW我也尝试过JDK 1.7.0_04,它也出现了问题。
答案 4 :(得分:-7)
据我所知,这个bug只能在服务器jvm中找到。如果你在客户端jvm上运行你的程序,你就是明确的。如果你在服务器jvm上运行你的程序,它取决于程序问题的严重程度。