1

慎重に作成された Java コードの多くが、java.lang.OutOfMemoryError によって無駄にされています。プロダクションクラスのコードでさえ、それによってダウンしてしまいます。

私が聞きたい質問は、このエラーの発生を回避できる優れたプログラミング/アーキテクチャの実践があるかどうかです。

したがって、Java プログラマーが自由に使えるツールは次のようになります。

  1. java.lang.Runtime.addShutdownHook(Thread hook) -- シャットダウン フックにより、正常な終了が可能になります。
  2. java.lang.Runtime.freeMemory() -- VM で使用可能なメモリを確認できます

したがって、私が考えたのは、オブジェクトを作成する前に、メモリを割り当てようとする前にシステムに十分なメモリが残っているかどうかをチェックするファクトリ メソッドを記述できるかということです。たとえば、C では、malloc が失敗し、理想的な状況ではなく、メモリー不足であることがわかりますが、単に java.lang.OutOfMemoryError 動脈瘤で死ぬことはありません。

推奨されるアプローチは、より適切なメモリ管理を行うか、メモリ リークを塞ぐか、単にメモリを増やすことです。これらは重要な点であることに同意しますが、次のシナリオを見てみましょう。

  1. Amazon マイクロ インスタンスで実行しています
  2. VM に割り当てられるメモリはごくわずかで、たとえば 400M です。
  3. Java プロセスはマルチスレッド方式でジョブを処理します。各スレッドは、計算タスクのパラメーターに応じてさまざまな量のメモリを消費します。
  4. 私のプロセスにメモリリークがないと仮定しましょう
  5. ジョブが完了する前にジョブを供給し続けると、最終的にはメモリ不足で死んでしまいます
  6. -Xmx を高く設定しすぎると、OS でスワッピングが発生し、スラッシングが発生する可能性があります。
  7. 同時実行の上限を設定すると、利用可能なRAMで実行できるジョブの受け入れを制限したり、さらに悪いことに、大量のメモリを必要とするジョブを受け入れたりして、最終的にjava.langにアクセスする可能性があるため、最適ではない可能性があります.OutOfMemoryError とにかく。X.質問の動機を説明するのに役立つことを願っています-標準的な回答は、問題に対するフォールトトレラントなアプローチを求めることと相互に排他的ではないと思います。

前もって感謝します。

4

2 に答える 2

2

JVM メモリは、アプリケーションで積極的に管理するものとしてではなく、チューニング パラメータとして扱いました。MemoryInfo クラスがあります (いくつかのランタイム メモリ情報メソッドをラップします)。

アプリケーションの実行中、アプリケーションの空きメモリを次のように追跡します。

 Runtime.getMaxMemory() - Runtime.getTotalMemory() + Runtime.getFreeMemory();

最大メモリは -Xmx jvm 引数、合計メモリは JVM がアプリケーション ヒープにすでに割り当てているもの、空きメモリは割り当てられたヒープ メモリのうちまだ使用可能な量です。( -Xms パラメーターが -Xmx パラメーターと同じである場合は、getFreeMemory()確認する必要があるのはそれだけです)。

メモリ使用量が 70% を超えると、監視システムにアラートが送信されます。その時点で、その日の残りをぐったりできるかどうか、または -Xmx パラメータを調整して再起動するかどうかを決定します。これは少し面倒に思えますが、実際には、一度システムを調整すると、その後メモリの問題が発生することはありません。(最大メモリ使用量が 90% を超えると、JVM は非常に頻繁に GC を実行して、メモリ不足を回避しようとします)。

すべての構造でメモリを管理するアプローチは厳格だと思いますが、絶対的な制御が必要な場合は、おそらく理にかなっています。もう 1 つの方法は、使用するすべてのメモリ キャッシュに LRU または有効期限とリロード メカニズムがあることを確認することです。これにより、メモリに保持されるオブジェクトの数をより適切に制限できます。

とはいえ、私たちのアプローチは、可能な限り多くのメモリを保持し、十分な RAM を割り当てることです。私たちの大規模なシステムには 28G の RAM が割り当てられています (平均して 40 ~ 60% を使用しています)。

于 2012-09-27T22:24:04.987 に答える
1

解決策は、以前に提案したように、必要なメモリを少なくすることです。プロセスは複数のリクエストを受け取るため、スレッドを無制限に実行しても意味がありません。各プロセスのスレッド数を制限し、最大でその数の要求を同時に処理します。残りのリクエストは単に待機します。

無制限の数のコアを持っているわけではないので、とにかく、スレッドが多すぎるのは悪い考えです.

于 2012-09-27T22:51:50.970 に答える