15

1つのJavaプロセス内で複数のRESTWebアプリケーションを実行して、メモリを節約し、Akkaを使用して簡単にスケーリングしたいと考えています。各リクエストハンドラが消費するメモリの量を見積もり、システム全体でこれらの危険を検出したいと思います。

  1. そのプロセス内でほぼリアルタイムでメモリ使用量を監視し、各リクエストハンドラで使用されているメモリの量を確認することは可能ですか?それを達成するために何が必要ですか?ツールはありますか?

  2. キャッチout of memory exceptionし、メモリ使用量に基づいて何かを行うことは可能ですか?たとえば、想定されるメモリ制限を超えるリクエストハンドラのみをクラッシュさせることはできますか?もしそうなら、それで何が悪いのでしょうか?

4

4 に答える 4

16

プログラムの使用済み/空きメモリの合計は、java.lang.Runtime.getRuntime()を介してプログラムで取得できます。

ランタイムには、メモリに関連するいくつかのメソッドがあります。次のコーディング例は、その使用法を示しています。

package test;

import java.util.ArrayList;
import java.util.List;

public class PerformanceTest {
  private static final long MEGABYTE = 1024L * 1024L;

  public static long bytesToMegabytes(long bytes) {
    return bytes / MEGABYTE;
  }

  public static void main(String[] args) {
    // I assume you will know how to create a object Person yourself...
    List<Person> list = new ArrayList<Person>();
    for (int i = 0; i <= 100000; i++) {
      list.add(new Person("Jim", "Knopf"));
    }
    // Get the Java runtime
    Runtime runtime = Runtime.getRuntime();
    // Run the garbage collector
    runtime.gc();
    // Calculate the used memory
    long memory = runtime.totalMemory() - runtime.freeMemory();
    System.out.println("Used memory is bytes: " + memory);
    System.out.println("Used memory is megabytes: "
        + bytesToMegabytes(memory));
  }
} 
于 2013-01-25T16:36:36.503 に答える
5

最初の質問に答えるために、メモリ使用量を監視するために使用できるツールはたくさんありますが、メモリ使用量を「リアルタイム」でスレッドにマッピングするアプリケーションはありません。アプリケーション内では、MemoryMXBeanおよびMemoryPoolMXBeansを使用して、メモリ使用量を監視できます。

2番目の質問に答えるには:いいえ、そうではありません。OOMEをキャッチすることは一般的に悪い考えであるという事実に加えて、主な問題は、例外を受け取るスレッドが実際の原因ではない可能性があることです。OOMEは、最終的な割り当て要求を行うスレッドでスローされます。ただし、他のスレッドがメモリの大部分をいっぱいにしたスレッドである可能性があります。もう1つの問題は、OOMEはいつでもスローされる可能性があるため、アプリケーション内の重要なコード内にスローされ、機能不全の状態のままになる可能性があることです。簡単に言うと、 OOMEを受け取ったら、ほとんどの場合、アプリケーションを再起動する必要があります。

于 2012-05-25T13:03:56.710 に答える
3

アプリケーションを監視するための優れた簡単なツールはVisualVMです。あなたはそれを試すことができます:http://visualvm.java.net/

于 2012-05-25T12:55:22.427 に答える
2

次のように、コードステートメントを追加して空きメモリを監視することもできます。

Runtime runtime = Runtime.getRuntime();
System.out.println("Free memory: " + runtime.freeMemory() + " bytes.");

この例外を処理することはできません。問題は、すべてのWebサービスを共通のアプリサーバー(Tomcatなど)で実行している場合、「メモリ不足」の例外が発生すると、JVMがダウンすることです。プログラムにメモリリークやメモリ処理の問題がないかどうかを確認してください。NetbeansまたはEclipse内でプロファイリングを使用できます。また、「findbugs」や「sonar」などのツールを使用したコード分析では、コード内で考えられる悪い習慣が示される場合があります。

いずれの場合も、ガベージコレクションまたはJVMメモリ(-Xmxなど)に関するJavaオプションを使用すると、このような例外を減らし、パフォーマンスを向上させることができます。

于 2012-05-25T13:04:32.823 に答える