1

同一のJavaバージョン「1.6.0_18」OpenJDKランタイム環境(IcedTea6 1.8)(fedora-36.b18.fc11-i386)OpenJDKサーバーVM(ビルド14.0-b16、混合モード)とすべて同一の6〜7台のサーバーのセットアップを想像してください

それぞれが何時間も何日もプログラムを実行し(メモリとCPUを集中的に使用)、何度も正常に完了します(そのような統計データを取得します)が、パラメーターや私がどのように準拠したかに関係なく、1台のマシンで(javac -source 1.5 * .java/javac -O -source 1.5, javac **, 自分で任意の組み合わせを想像してみてください :))
またはそれを実行しました (-Xms200000k または単に Java blabla.java を考えてみてください)

私は最終的に、特定の瞬間や反復ではなく、「java.lang.ArrayIndexOutOfBoundsException: -1341472392」を取得します?! まず第一に、プログラムはそのような大きな値では機能しません。(コード行は、整数を含む ArrayList の呼び出しを含む) (私が気づいたように、その数は毎回異なります)

また、クラッシュしたテストを「再開」でき、このマシンでできることにも注意してください。さらにいくつかのテストを実行すると、再びクラッシュします。

私はボックスを所有しておらず、他のすべてが機能していますが、これは私にとって非常に奇妙です.

個人的な興味から、あまりバラ色ではない OpenJDK でこれがどのように発生するのでしょうか?

4

2 に答える 2

3

奇妙に聞こえます。配列のインデックス付けに使用される変数は long ですか、それとも long 変数の影響を受けますか? その場合、変数へのアクセスがアトミックであるとは限りません。

http://java.sun.com/docs/books/jls/second_edition/html/memory.doc.html#28733から

double または long 変数が volatile であると宣言されていない場合、ロード、ストア、読み取り、および書き込みアクションの目的で、それらはそれぞれ 32 ビットの 2 つの変数であるかのように扱われます。アクションは、32 ビットの半分ごとに 1 つずつ実行されます。double または long 変数の 64 ビットが 2 つの 32 ビット量にエンコードされる方法は、実装に依存します。volatile 変数に対するロード、ストア、読み取り、および書き込みアクションは、変数の型が double または long であってもアトミックです。

これが問題である可能性があると思われる場合は、index-variable を volatile として宣言するか、他の同期手段 (たとえば、AtomicLong などを使用) を使用することができます。

于 2010-07-05T13:33:16.503 に答える
0

これがシングルスレッドの Java アプリケーションである場合、ハードウェアの障害が疑われます。もちろん、ハードウェア (メモリなど) の診断を実行する方法がない限り、これを証明するのは困難です。

于 2010-07-05T14:30:02.880 に答える