web-dev-qa-db-ja.com

JVM Tenured / Old genが制限に達し、サーバーがハングする

私たちのアプリケーションは非常に大きなデータを扱うため、非常に大きなメモリを必要とします。したがって、最大ヒープサイズを12GB(-Xmx)に増やしました。

以下は環境の詳細です

OS - Linux 2.6.18-164.11.1.el5    
JBoss - 5.0.0.GA
VM Version - 16.0-b13 Sun JVM
JDK - 1.6.0_18

QAと製品には上記の環境と設定があります。 QAでは、最大PS Old Gen(ヒープメモリ)が8.67GBとして割り当てられていますが、製品版では8GBです。

特定のジョブの製品では、Old Genヒープが8GBに達し、そこでハングし、Web URLにアクセスできなくなります。サーバーがダウンしています。しかし、QAでも8.67GBに達しますが、フルGCが実行され、6.5GB程度に戻ります。ここでは絞首刑にならない。

両方のボックスの環境と構成が同じであるため、この解決策を見つけることができませんでした。

ここに3つの質問があります。

最大ヒープの2/3は、古い世代または保有世代に割り当てられます。それが、ある場所で8GB、別の場所で8.67GBである理由は何ですか?

この場合(12GB)の新入社員の有効な比率を提供するにはどうすればよいですか?

ある場所で完全なGCが行われ、他の場所では行われないのはなぜですか?

どんな助けでも本当にありがたいです。ありがとう。

Plsは、envまたはconfの詳細が必要かどうかを知らせます。

22
raksja

特定の質問:

  1. 新世代と旧世代のデフォルトの比率は、システムと、JVMが最適と判断するものによって異なります。
  2. -XX:NewRatio=3を使用して、新世代と旧世代の特定の比率を指定します。
  3. JVMがハングしていて、ヒープがいっぱいの場合、おそらく一定のGCを実行してスタックしています。

Prodにはより多くのメモリが必要なようです。 QAでリクエストが終了した場合、おそらく0.67GBの追加で十分です。しかし、それでも十分な余裕はありません。 QAで本番と同じテストを実行していますか?

12GBを使用しているため、64ビットを使用する必要があります。 -XX:+UseCompressedOopsオプションを使用すると、64ビットアドレッシングのメモリオーバーヘッドを節約できます。通常、メモリが40%節約されるため、12GBはさらに大きくなります。

実行していることに応じて、特に長いGC一時停止時間を短縮するために、並行コレクターの方が適している場合もあります。これらのオプションはうまく機能することがわかっているので、試してみることをお勧めします。

-Xmx12g -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC
-XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled
-XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68
22
WhiteFang34

何が起こっているのかを知るためには、さらにデータを取得する必要があります。そうしないと、何を修正する必要があるのか​​がわかります。それは私の心に

  1. ガベージコレクターの動作に関する詳細情報を取得します。これらのパラメーターは良い出発点です(gc.logの代わりにいくつかの優先パスとファイルを使用してください)

    -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -Xloggc:gc.log -verbose:gc

  2. 実行を繰り返し、ハングしている期間のgcログをスキャンし、その出力でポストバックします。

  3. visualgcを使用して出力を監視することを検討してください(サーバーでjstatdを実行する必要があります。この設定を行う方法を説明する1つのランダムリンクは this one )であり、 jvmstat 、これは、ヒープ内のさまざまな世代がどのようにサイズ設定されているかを確認する簡単な方法です(ただし、6時間ではありません!)

また、これらのすべてのスイッチが何を参照しているかを理解するために、いくつか読んでおくことを強くお勧めします。 Oracle Java 6 gcチューニングページから始めます こちら

ベースラインパフォーマンスが得られたら、オプションを変更することをお勧めします。 CompressedOopsは簡単に勝てる可能性が高いと言いましたが、6u23以降、デフォルトでオンになっていることに注意してください。

最後に、jvmのアップグレードを検討する必要があります。6u18は少し進んでおり、パフォーマンスは向上し続けています。

各ジョブの完了には3時間かかり、ほぼ6つのジョブが次々と実行されます。実行中の最後のジョブが最大8GBに達し、製品でハングする

これらの仕事はまったく関連していますか?同じデータセットで作業していない場合、これは徐々にメモリリークのように聞こえます。ヒープ使用量が増え続け、最終的にはブローする場合は、メモリリークがあります。ヒープダンプをキャッチするには、-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/some/dirの使用を検討する必要があります(13Gヒープでは大きなファイルになるため、ディスク領域があることを確認してください)。次に、 jhat を使用して、その時点でヒープ上にあったものを確認できます。

3
Matt