Java 7 Hotspot 循环 Bug 详解

阅读数:3069 2011 年 8 月 4 日

话题:JavaOracle语言 & 开发

上周 Java 7 GA 发布后,新 JIT 默认开启的优化中发现了一个问题。虽然这个问题最早是在Lucene搜索索引器的一个用例中出现的,但是它也有可能普遍存在于其他代码之中。

这个 Bug 引来了不少杞人忧天的文章,例如《Don't use Java 7 for anything》,其中暗示所有循环都有问题。事实上,虽然存在一个有效的 Bug(循环可能无法正确执行或者引起 SIGSEGV 崩溃),但是这个 Bug 从 Java 6 开始就有了,如果开启了-XX:+OptimizeStringConcat-XX:+AggressiveOpts优化就会发生这个问题。

这个问题实际只会发生在特定的循环(循环体可能会修改循环条件)中,该问题的补丁中对此做了说明。在以-Xint(解释模式)运行的情况下不会发生这个问题,但在-server模式下就会有问题,服务器端应用程序很有可能就会使用这种模式。

如果问题不算太严重,出于此 Bug 带来的公众压力,Java 7 Update 1 中会包含该补丁。由于 Java 7 刚刚发布,目前还不会被用于生产环境,而且它也不是这方面发现的第一个问题(Oracle 在后续版本中修复了这个问题)。与此同时,问题描述中指出可以通过 -XX:-UseLoopPredicate标志来关闭这个特定的优化。

在 Lucene 和 Solr 项目中最早发现该问题的 Uwe Schindler 详细记录了Bug 背后的故事,包含后续的反应(以及过激反应)。他记录到 Twitter 上大家的反应和后续的文章将 Bug 的优先级提高了,它的补丁将被放在 Java 7 Update 1 中,而不是 Java 7 Update 2。但是,他也说了,尽管高优先级 Bug(会导致 SIGSEGV)会在 Java 7 Update 1 中修复,但是还有两个其他Bug 仍是中优先级。

正如Robert Muir分析中所说的,因为这些优化都是在循环最少 10,000 次后才被引入的,所以很多测试都覆盖不到。已经有了补丁,会纳入以后的 Java 7 更新中,禁用 LoopPredicate 优化也能让 Java 7 摆脱这些问题。

查看英文原文:Java7 Hotspot Loop Bug Details