[解決済み] Java: int 型配列が 0 ではない要素で初期化される。
質問
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の最適化によって制限されていることは明らかです。このような動作の理由のための任意のアイデア?
更新しました。
Gentoo Linux, Debian Linux (both kernel 3.0 version) および MacOS Lion 上の HotSpot 64-bit server VM, Java version 1.7.0_04 から 1.7.0_10 でこの挙動が確認されました。このエラーは、上記のコードで必ず再現できます。32bitのJDKやWindowsではこの問題をテストしていません。私はすでにOracleにバグレポートを送信しており(バグID 7196857)、数日中に公開Oracleバグデータベースに表示される予定です。
更新しました。
Oracle 社は、このバグを公開バグデータベースで公開しました。
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857
どのように解決するのですか?
ここで、JITコンパイラのバグに直面します。コンパイラは、アロケートされた配列が
Arrays.fill(...)
の中でアロケートされた配列が満たされたと判断しますが、アロケートと充填の間の用途のチェックに欠陥があります。そのため、コンパイラは不正な最適化を実行し、割り当てられた配列のゼロ化をスキップしてしまいます。
このバグは Oracle のバグトラッカー ( バグID 7196857 ). 残念ながら、私は以下の点についてOracleからの説明を待たなかった。私の見るところ、このバグはOSに依存します。64ビットのLinuxとMacでは絶対に再現しますが、コメントで見るところ、Windowsでは(JDKの類似バージョンでは)定期的に再現しません。さらに、このバグがいつ修正されるかを知ることは良いことだと思います。
現時点で唯一のアドバイスは、新しく宣言された配列のために JLS に依存している場合、JDK1.7.0_04 またはそれ以降を使用しないことです。
10 月 5 日に更新しました。
新しい ビルド 10 で、このバグは少なくとも Linux OS では修正されています。このバグがOracleのバグデータベースで公開されていないことを発見してくれた@Makotoさんに感謝します。残念ながら、Oracleが公開を中止した理由は分かりませんが、Googleでは公開されています。 キャッシュ . また、このバグは Redhat の注意を引きました: CVE 識別子 CVE-2012-4420 ( バグジラ ) と CVE-2012-4416 ( バグジラ ) がこの欠陥に割り当てられていました。
関連
-
[解決済み】空の配列要素を削除する
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み] Javaで配列に特定の値が含まれているかどうかを判断するにはどうすればよいですか?
-
[解決済み] Javaで配列を宣言し、初期化する方法は?
-
[解決済み] Java の配列を表示する最も簡単な方法は何ですか?
-
[解決済み] JavaScriptで配列の先頭に新しい配列要素を追加するにはどうすればよいですか?
-
[解決済み] Javascriptで配列から空の要素を削除する
-
[解決済み] Javaで汎用配列を作成する方法は?
-
[解決済み] Javaで配列をリストに変換する
-
[解決済み】JavaScriptで配列の要素を削除する - delete vs splice
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
アクセス制限です。タイプ 'JPEGCodec' は API ではない ☞My Blog Github ☜ ホームページを見る
-
java.sql.SQLException: executeQuery()でデータ操作文を発行できません。
-
無効な文字定数
-
無効なメソッド宣言
-
セミコロン期待値エラー解決
-
keytool error: java.io.FileNotFoundException: cacerts (アクセス拒否されました。)
-
Javaがリソースリークに遭遇した:'input'が閉じない 解決方法
-
git pull appears現在のブランチに対するトラッキング情報がありません。
-
Java:未解決コンパイル問題の解決方法
-
java 365*1000*60*60*24 計算問題