ソケットを介してリクエストを処理し、各リクエストを処理するスレッドを生成するサーバーがあります。
が表示されるのはなぜjava.lang.OutOfMemoryError
ですか? 修正するにはどうすればよいですか?
ソケットを介してリクエストを処理し、各リクエストを処理するスレッドを生成するサーバーがあります。
が表示されるのはなぜjava.lang.OutOfMemoryError
ですか? 修正するにはどうすればよいですか?
タイプ I: ヒープ領域が不足しています。
これは最も一般的なエラーです。どのオブジェクトが「正常」で、どのオブジェクトを解放する必要があるかを理解する必要があるため、追跡するのは難しい場合があります。
無限の量の参照オブジェクトを作成します。スレッド固有であるが、もう 1 つのグローバル オブジェクトによって参照されるオブジェクトを作成します。
問題を再現できる場合は、実行中jmap -dump:format=b,file=output.bin
次に、ヒープ ファイルをjhat
.
タイプ II: アウト オブ プロセス メモリ
JNI 呼び出しを実装した場合、または JNI オブジェクトを作成する JVM によってユーザーに代わって作成されたオブジェクトがある場合、プロセス メモリが不足する可能性があります。これは、32 ビット プロセスの場合は 4 ギガです。
実行中の Java プロセスのプロセス空間は、次のもので構成されます。
JVM メモリの-Xmx
サイジングのみを制御します。
タイプ III: ガベージ コレクタが実行されない
Web 検索で、この状況に関する言及は見つかりませんでした。解決のためにすべての投稿を読んだと思いますjava.lang.OutOfMemoryErrors
。
ネイティブ コードへの JNI 呼び出しを行う Java プログラムがある場合、スレッドが JNI 呼び出しにある間、ガベージ コレクターは実行されません。JNI 呼び出しに 2 つ以上のスレッドがある十分にビジーなシステムがある場合、ガベージ コレクターが実行されない可能性があります。
最初のインスタンスは、コールバックを Java コードに作成して現在のオブジェクトを解放し、新しいオブジェクトを取得する長時間実行される JNI 呼び出しでした。繰り返しごとに、使用されるメモリの量が増加し、未使用のオブジェクトはガベージ コレクションされませんでした。
2 番目のインスタンスは、生成されたすべてのスレッドが JNI 呼び出しを引き起こすテストでした。コードは非常に長い時間 (約 1 時間程度) 実行されますが、java.lang.OutOfMemoryError
. この-Xloggc
オプションは、実行中の同時スレッド数が増加するまで、最初の 4000 秒間の定期的なガベージ コレクションを示しました。
4055.330: [GC 4055.330: [ParNew: 147424K->12220K(147456K), 0.0073372 secs] 769563K->637289K(1294336K) icms_dc=0 , 0.0073809 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
18668.710: [GC 18668.710: [ParNew: 143289K->16384K(147456K), 0.0297121 secs] 768358K->651851K(1294336K) icms_dc=0 , 0.0297604 secs]
[2014 年 6 月 7 日更新] あるインスタンスで、この回答を見つけましたJNI を使用して C から Java コードを呼び出すときのメモリ リークの問題が修正されました。ローカル Java メモリは、JNI 呼び出し内から作成されるため、Java で割り当てられている場合でも C スタックに割り当てられます。具体的には、Java へのバックコールを PushLocalFrame()/PopLocalFrame() でラップして問題を修正しました。