8

私の単純な目標は、Java アプリケーションのメモリ使用量を監視して、アプリケーションがOutOfMemoryError.

はい、言うのは簡単ですが、正しい解決策を考え出すことは非常に複雑に思えます。複雑な要因のいくつかは次のとおりです。

  • さまざまなヒープ領域があり、それぞれが次をスローできますOutOfMemoryError
    • 独自のpermgenサイズ制限があるスペース ( で設定-XX:MaxPermSize=)
    • 全体のヒープ領域 ( で設定-Xmx)
  • VM は、ガベージ コレクションを実行する前に、ほぼすべてのヒープを割り当てる可能性があります。アプリケーションが多くのソフト参照を使用している場合、実際、これは確実に発生します。したがって、ヒープ割り当てのパーセンテージが高いからといって、アプリケーションがOutOfMemoryError.
  • System.gc()VM が再利用可能なすべてのオブジェクト (参照されていないオブジェクトや弱く参照されているオブジェクト) を再利用することが保証されていればよいのですが、そうではありません。そのため、呼び出しSystem.gc()てからRuntime.freeMemory()信頼できません。
  • ファイナライズのためにキューに入れられたオブジェクトはメモリを占有しますが、(通常は) ファイナライズ後に解放されます。したがって、ファイナライザー スレッドがそれらに到達したかどうかは、(見かけの) メモリ使用量に影響します (VM は、OOM をスローする前の最後の絶望的な行為としてファイナライザーを実行しますか?そのようには見えません。 )
  • ネイティブ コードも同様にメモリを消費し、使いすぎると OOM が発生する可能性があります (これは私の特定のアプリケーションでは起こりそうにありませんが、全体像に別の複雑さを追加します)。

では、次の質問に答える適切で信頼できる方法は何でしょうか:私の Java アプリケーションは をスローするようになっていOutOfMemoryErrorますか?

別の言い方をすれば、アプリケーション バージョン X は問題なく動作し、メモリ リークもありませんが、バージョン X + 1 には認識されない遅いメモリ リークがあるとします。バージョン X + 1 が をスローする前に、この監視によってアラートを受け取りOutOfMemoryErrorたいのですが、まったく同じ監視でバージョン X の誤検知が発生しないようにしたいと考えています。この監視の設定には調整が必要な場合があります。問題ありません.

考えられる答えの 1 つは次のようなものかもしれません: 過去 N 回の「完全な」GC 実行における、GC 実行直後のヒープ使用率の最大値は? この値が割り当てられたメモリの合計の X% を超える場合は、アラームを鳴らします。

アイデアは、「アプリケーションのメモリ使用量」をパーセンテージなどの単純な数値、または LOW、MEDIUM、HIGH などの数値で判断し、この値を監視することです。

jstatコマンドは多くの関連情報を提供しますが、問題はそれを単純な答えに要約し、上記の複雑な要因によって引き起こされる誤検知 (または誤検知) を回避することです。

4

2 に答える 2

7

長時間実行されているアプリケーションのメモリ グラフ (たとえば、jconsole などのツールで収集) を見ると、特徴的な鋸歯状のパターンが見られます。メモリ使用量が上昇し、GC によってベースラインに戻り、その後上昇します。また。正常なアプリの場合、山と谷は 2 本の水平の直線になっています。ただし、リークしているアプリの場合、ベースラインは上昇します。これは実際に監視する必要があることです。連続する各 GC が前回よりも効果が低い場合、デンマークでは何かが腐っています。

于 2013-06-07T15:49:09.307 に答える
0

Oracle のドキュメント ページでこの用語Detecting Low Memoryを検索するThreshold Notificationsと、組み込みの MXBean に基づいてアラート システムを考案できる場合があります。ガベージ コレクションは、少なくともいくつかのメトリック コレクションの焦点のようです。

于 2013-06-10T21:19:23.827 に答える