JLSによると、int
配列は初期化の直後にゼロで埋められる必要があります。しかし、そうではない状況に直面しています。このような動作は、JDK 7u4で最初に発生し、その後のすべての更新でも発生します(私は64ビット実装を使用しています)。次のコードは例外をスローします。
public static void main(String[] args) {
int[] a;
int n = 0;
for (int i = 0; i < 100000000; ++i) {
a = new int[10];
for (int f : a)
if (f != 0)
throw new RuntimeException("Array just after allocation: "+ Arrays.toString(a));
Arrays.fill(a, 0);
for (int j = 0; j < a.length; ++j)
a[j] = (n - j)*i;
for (int f : a)
n += f;
}
System.out.println(n);
}
例外は、JVMがコードブロックのコンパイルを実行した後に発生し、-Xint
フラグでは発生しません。さらに、Arrays.fill(...)
ステートメント(このコードの他のすべてのステートメントと同様)が必要であり、このステートメントがない場合は例外は発生しません。この考えられるバグは、JVMの最適化に関係していることは明らかです。そのような行動の理由について何かアイデアはありますか?
更新:
HotSpot 64ビットサーバーVM、Gentoo Linux、Debian Linux(両方のカーネル3.0バージョン)、MacOS LionのJavaバージョン1.7.0_04から1.7.0_10でこの動作が見られます。このエラーは常に上記のコードで再現できます。32ビットJDKまたはWindowsでは、この問題をテストしていません。私はすでにOracleにバグレポートを送信しており(バグID 7196857)、数日以内にパブリックOracleバグデータベースに表示されます。
更新:
Oracleはこのバグを公開バグデータベースhttp://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857で公開しました