私はJavaを実行していますjava -Xmx240g mypackage.myClass
OSはUbuntu12.10です。
top
はMiB Mem 245743 total
、Java プロセスがvirt 254g
最初からあり、res
まで着実に増加していることを示してい169g
ます。その時点でガベージ コレクションが大量に開始されるように見えますが、その時点でプログラムはシングル スレッドであり、CPU%
ほとんど100%
がこの時点までであり、この時点で約 1300 ~ 2000 にジャンプするためだと思います (私はそれがマルチスレッド ガベージ コレクタ)、res
ゆっくりと に移動し172g
ます。その時点でJavaはクラッシュします
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
との行でnew double[2000][5]
java -version
言う
java version "1.7.0_15"
OpenJDK Runtime Environment (IcedTea7 2.3.7) (7u15-2.3.7-0ubuntu1~12.10)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
ハードウェアは Amazon cr1.8xlarge インスタンス
利用可能なメモリがたくさんある場合でも、Java がクラッシュするように思えます。明らかに不可能です。いくつかの数字を間違って解釈する必要があります。何が起こっているのかを理解するには、どこを見ればよいですか?
編集:
GC オプションは指定しません。唯一のコマンドラインオプションは-Xmx240g
私のプログラムは多くの入力を正常に処理しtop
ており、最大 98.3% のメモリを使用していると言われています。ただし、特定のプログラム入力で上記の状況を再現しました。
編集2:
これは科学的応用です。巨大なツリー (100 万から 1000 万のノード) があり、各ノードにはdouble
サイズが約 2 つの配列があります。300x3 - 900x5。最初のツリー作成後、プログラムは多くのメモリを割り当てません。ほとんどの場合、これらの配列に対していくつかの算術演算が行われます。
編集3:
HotSpot JVM も同じように停止し、CPU を 170 ~ 172g マークで大量に使用し、同じエラーでクラッシュしました。メモリの 70 ~ 75% は、JVM が越えたくない魔法の境界線のようです。
最終的な解決策: -XX:+UseConcMarkSweepGC -XX:NewRatio=12 の場合、プログラムは 170g のマークを通過し、さらに進んでいます。