先週Java 7が正式リリースされた後、JITコンパイラがデフォルトで行う最適化のうちの1つに問題が見つかった。これは最初、Luceneのサーチインデクサで発見されたが、この問題は他のコードにも広く影響を及ぼす可能性がある。
このバグは、数多くの人騒がせな記事が書かれるきっかけとなった(例えば、全てのループが問題を含んでいるかのようなニュアンスを含んだ“決してJava 7を使ってはいけない”)。実は、ループが正しく展開されずにSIGSEGVを発生させてしまうこの最適化の問題は、-XX:+OptimizeStringConcat
か-XX:+AggressiveOpts
の最適化が有効になっていればJava 6でも発生しうる。
実際には、この問題はここに書かれているように、特定のループ(ループの中で変化する条件を使っている場合)でのみ発生する。-Xint
(インタープリタモード)で実行した場合は発生しないが、ほとんどのサーバーサイドアプリケーションが使っているであろう-server
モードで実行した場合には、この問題が発生してしまう。
このバグに対する世間の圧力は強く、そのためこのバグはJava 7 Update 1で修正されることになりそうだ。Java 7はリリースされたばかりなので、まだ本番環境では使われていないだろう。また、これは初めて発見された問題というわけではないようだ(後のリリースで修正された)。パッチがリリースされるまでの間は、バグデータベースにある通り、-XX:-UseLoopPredicate
オプションでこの最適化を無効にすればよいようだ。
LuceneとSolrプロジェクトを使っていてこの問題を見つけたUwe Schindler氏は、その後に生じたリアクション(とオーバーリアクション)を含む、バグの裏話を詳細に投稿した。その中でUwe氏は、Twitterやそれに続くブログでの反応によってバグの優先度が上がり、結果として対応が先延ばしにされず、Java 7 Update 1で修正されることになるだろうと述べている。また、SIGSEGVの原因となるこのバグは、Java 7 Update 1で対応されると期待できるが、問題を発生させる可能性のあるこのバグやこのバグはまだ優先度が中と評価されている、とも述べている。
これらの最適化は、ループが最低でも10,000回実行された後に行われるので、多くのテストでは何も問題が起こらない可能性がある。それについては、Robert Muir氏が詳細に説明している。このバグはコードレベルではすでに解消されており、今後のJava 7の修正パッチに含まれることになるだろう。それまでの間は、LoopPredicate最適化を無効にするオプションを使ってJava 7を動かせばよい。