モジュール java.management
パッケージ java.lang.management

インタフェースMemoryPoolMXBean

すべてのスーパー・インタフェース:
PlatformManagedObject

public interface MemoryPoolMXBean extends PlatformManagedObject
メモリー・プールの管理インタフェースです。 メモリー・プールは、Java仮想マシンにより管理されるメモリー・リソースを表し、1つ以上のメモリー・マネージャにより管理されます。

Java仮想マシンは、このインタフェースの実装クラスの1つ以上のインスタンスを持ちます。 このインタフェースを実装するインスタンスは、ManagementFactory.getMemoryPoolMXBeans()メソッドまたはplatform MBeanServerメソッドを呼び出すことによって取得できるMXBeanです。

MBeanServer内でメモリー・プールのMXBeanを一意に識別するためのObjectNameは次のとおりです。

java.lang:type=MemoryPool,name=pool's name
これを取得するには、PlatformManagedObject.getObjectName()メソッドを呼び出します。

メモリーの型

Java仮想マシンは、オブジェクト割当て用のヒープを持ち、メソッド領域とJava仮想マシンの実行用のヒープ以外のメモリーも保持しています。 Java仮想マシンは、1つ以上のメモリー・プールを保有できます。 各メモリー・プールは次の型のどちらかのメモリー領域を表します。

メモリー使用量の監視

メモリー・プールには、次の属性があります。

1. メモリー使用量

getUsage()メソッドは、メモリー・プールの現在の使用量の推定値を提供します。 ガベージ・コレクトされたメモリー・プールの場合は、usedメモリーの量にプール内のすべてのオブジェクト(到達できるオブジェクトおよび到達できないオブジェクトの両方を含む)によって占有されるメモリーが含まれます。

一般に、このメソッドは負荷の少ない操作でおよそのメモリー使用量を取得します。 オブジェクトが連続してパックされない場合など、一部のメモリー・プールでは、このメソッドは現在のメモリー使用量を判定するのにいくらかの計算を必要とする負荷の大きい操作になる可能性があります。 実装は、該当する状況をドキュメント化する必要があります。

2. ピーク・メモリー使用量

Java仮想マシンは、Java仮想マシンが起動されたり、ピーク・メモリー使用量がリセットされたりしてからのメモリー・プールのピーク・メモリー使用量を保持します。 ピーク・メモリー使用量は、getPeakUsage()メソッドによって返され、resetPeakUsage()メソッドの呼出しによってリセットされます。

3. 使用量しきい値

各メモリー・プールは、使用量しきい値という管理可能な属性を持ち、このしきい値はJava仮想マシンが指定したデフォルト値を持ちます。 デフォルト値はプラットフォームに応じて異なります。 使用量しきい値は、setUsageThresholdメソッドを使って設定できます。 しきい値が正の値に設定されると、このメモリー・プールで使用量しきい値の超過チェックが有効になります。 使用量しきい値がゼロに設定されると、このメモリー・プールで使用量しきい値の超過チェックが無効になります。 isUsageThresholdSupported()メソッドを使えば、この機能がサポートされているかどうかを判定できます。

Java仮想マシンは、最適な時期(通常はガベージ・コレクション時)に、使用量しきい値超過チェックをメモリー・プールごとに実行します。 各メモリー・プールは、メモリー・プール使用量がしきい値を超過していることをJava仮想マシンが検出するたびに増加する使用量しきい値カウントを保持しています。

この管理可能な使用量しきい値属性は、メモリー使用量の増加傾向を低いオーバーヘッドで監視するように設計されています。 使用量しきい値は、一部のメモリー・プールに適さない場合があります。 たとえば、多くのJava仮想マシン実装で使用される共通のガベージ・コレクタである世代別ガベージ・コレクタは、年齢でオブジェクトを区分して、2世代以上を管理します。 ほとんどのオブジェクトは、もっとも若い世代 (若いメモリー・プール)に割り当てられます。 若いメモリー・プールは、いっぱいになるように設計されています。また、ガベージ・コレクション時にほとんどの場合到達不可能な短期間稼動のオブジェクトが収容されるため、若いメモリー・プールを収集すると、メモリー空間のほとんどが解放されます。 このケースでは、若いメモリー・プールが使用量しきい値をサポートしないほうが適切です。 加えて、使用量のしきい値と比較するときのオーバーヘッドは、オブジェクト割当てのコストよりも高くつくので、1つのメモリー・プールへのオブジェクトの割当てのコストがきわめて低い場合(例、原子ポインタ交換など)、Java仮想マシンはメモリー・プールの使用量しきい値をサポートしません。

システムのメモリー使用量は、ポーリングしきい値通知のメカニズムを使って監視できます。

  1. Polling

    アプリケーションでは、すべてのメモリー・プール共通のgetUsage()メソッド、または使用量しきい値をサポートするメモリー・プール専用のisUsageThresholdExceeded()メソッドを呼び出すことにより、アプリケーション自体のメモリー使用量を継続的に監視できます。 次に、タスクの配分と処理に特化したスレッドを持つサンプル・コードを示します。 このサンプル・コードは、どの区間でもメモリー使用量に基づいて新しいタスクを受け入れて処理するかどうかを判定します。 メモリー使用量が使用量しきい値を超えた場合、このサンプル・コードはすべての未処理のタスクをほかの仮想マシンに再配分し、メモリー使用量が使用量しきい値以下に戻るまで新しいタスクの受け入れを停止します。

           // Assume the usage threshold is supported for this pool.
           // Set the threshold to myThreshold above which no new tasks
           // should be taken.
           pool.setUsageThreshold(myThreshold);
           ....
    
           boolean lowMemory = false;
           while (true) {
              if (pool.isUsageThresholdExceeded()) {
                  // potential low memory, so redistribute tasks to other VMs
                  lowMemory = true;
                  redistributeTasks();
                  // stop receiving new tasks
                  stopReceivingTasks();
              } else {
                  if (lowMemory) {
                      // resume receiving tasks
                      lowMemory = false;
                      resumeReceivingTasks();
                  }
                  // processing outstanding task
                  ...
              }
              // sleep for sometime
              try {
                  Thread.sleep(sometime);
              } catch (InterruptedException e) {
                  ...
              }
           }
           

    上記サンプル・コードは、メモリー使用量が一時的に使用量しきい値を下回ったケースを、2つの反復間でメモリー使用量がしきい値を超えたままであるケースから区別していません。 getUsageThresholdCount()メソッドにより返された使用量しきい値カウントを使って、返されたメモリー使用量が2つのポール間でしきい値以下であるかどうかを判定できます。

    次に示すのは、メモリー・プールがメモリー不足の場合に何らかのアクションを実行し、アクション処理中にメモリー使用量の変化を無視するサンプル・コードです。

           // Assume the usage threshold is supported for this pool.
           // Set the threshold to myThreshold which determines if
           // the application will take some action under low memory condition.
           pool.setUsageThreshold(myThreshold);
    
           int prevCrossingCount = 0;
           while (true) {
               // A busy loop to detect when the memory usage
               // has exceeded the threshold.
               while (!pool.isUsageThresholdExceeded() ||
                      pool.getUsageThresholdCount() == prevCrossingCount) {
                   try {
                       Thread.sleep(sometime)
                   } catch (InterruptException e) {
                       ....
                   }
               }
    
               // Do some processing such as check for memory usage
               // and issue a warning
               ....
    
               // Gets the current threshold count. The busy loop will then
               // ignore any crossing of threshold happens during the processing.
               prevCrossingCount = pool.getUsageThresholdCount();
           }
           

  2. 使用量しきい値通知

    使用量しきい値通知は、MemoryMXBeanにより発行されます。 メモリー・プールのメモリー使用量が使用量しきい値に達したか超えたことをJava仮想マシンが検出すると、仮想マシンはMemoryMXBeanをトリガーして使用量しきい値超過通知を発行します。 使用量がしきい値未満になり、再び超過するまで、別の使用量しきい値超過通知は生成されません。

    次のサンプル・コードは、前述の最初のサンプル・コードと同じロジックを実装していますが、ポーリングではなく、使用量しきい値通知メカニズムを使ってメモリー不足条件を検出しています。 このサンプル・コードでは、通知の受け取りにより、通知リスナーは未処理タスクの再配分、タスクの受け取りの停止、あるいは受け取りタスクの再開などの実際のアクションを実行するよう別のスレッドに通知します。 handleNotificationメソッドは、きわめて少量の作業を実行して遅延なしに値を返し、以降の通知の配布で遅延が生じないように設計される必要があります。 時間のかかるアクションは別のスレッドにより実行される必要があります。 通知リスナーは、複数のスレッドにより呼び出されることができます。したがって、リスナーが実行するタスクは適切に同期化される必要があります。

           class MyListener implements javax.management.NotificationListener {
                public void handleNotification(Notification notification, Object handback)  {
                    String notifType = notification.getType();
                    if (notifType.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) {
                        // potential low memory, notify another thread
                        // to redistribute outstanding tasks to other VMs
                        // and stop receiving new tasks.
                        lowMemory = true;
                        notifyAnotherThread(lowMemory);
                    }
                }
           }
    
           // Register MyListener with MemoryMXBean
           MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
           NotificationEmitter emitter = (NotificationEmitter) mbean;
           MyListener listener = new MyListener();
           emitter.addNotificationListener(listener, null, null);
    
           // Assume this pool supports a usage threshold.
           // Set the threshold to myThreshold above which no new tasks
           // should be taken.
           pool.setUsageThreshold(myThreshold);
    
           // Usage threshold detection is enabled and notification will be
           // handled by MyListener.  Continue for other processing.
           ....
    
           

    MemoryMXBeanがしきい値通知を発行する時期や通知が配布される時期についての保証はありません。 通知リスナーが呼び出されると、メモリー・プールのメモリー使用量が使用量しきい値を2回以上超えた可能性があります。 MemoryNotificationInfo.getCount()メソッドは、通知が構築された時点でメモリー使用量が使用量しきい値を超えた回数を返します。 この回数を、getUsageThresholdCount()メソッドにより返された現在の使用量しきい値カウントと比較して、このような状況が発生したかどうかを判定できます。

4. コレクション使用量しきい値

一部のガベージ・コレクトされたメモリー・プールだけに適用できる管理可能な属性です。 Java仮想マシンが、ガベージ・コレクション時にメモリー・プールにある使用しないオブジェクトをリサイクルすることで、メモリー空間を再生することに最善を尽くしたあと、ガベージ・コレクトされたメモリー・プールにある一部のバイト数はそれでも使用中です。 しきい値を超過した場合、MemoryMXBeanによってコレクション使用量しきい値超過通知が発行されるように、コレクション使用量しきい値を使って、この一部のバイト数に値を設定できます。 加えて、コレクション使用量しきい値カウントが増やされます。

isCollectionUsageThresholdSupported()メソッドを使えば、この機能がサポートされているかどうかを判定できます。

Java仮想マシンは、コレクション使用量しきい値チェックをメモリー・プールごとに実行します。 このチェックは、コレクション使用量しきい値が正の値に設定されている場合に有効になります。 コレクション使用量しきい値がゼロに設定された場合、このチェックはこのメモリー・プールで無効になります。 デフォルト値はゼロです。 Java仮想マシンは、ガベージ・コレクション時にコレクション使用量しきい値チェックを実行します。

一部のガベージ・コレクトされたメモリー・プールでは、コレクション使用量しきい値をサポートしないように選択できます。 たとえば、メモリー・プールは連続的な並行ガベージ・コレクタだけにより管理されます。 使用しないオブジェクトを並行ガベージ・コレクタが同時に再生している間に、何らかのスレッドにより、このメモリー・プールにオブジェクトを割り当てることができます。 十分に定義されたガベージ・コレクション時間(メモリー使用量をチェックするのに最適な時間)がないかぎり、コレクション使用量しきい値をサポートしてはいけません。

コレクション使用量しきい値は、Java仮想マシンがメモリー空間の再生に最善を尽くしたあと、メモリー使用量を監視するよう設計されています。 使用量しきい値で説明したポーリングおよびしきい値通知メカニズムにより、同様の方法でコレクション使用量を監視できます。

導入されたバージョン:
1.5
関連項目:
ManagementFactory.getPlatformMXBeans(Class), JMX仕様, MXBeanにアクセスする方法
  • メソッドのサマリー

    修飾子と型
    メソッド
    説明
    Java仮想マシンがこのメモリー・プールで使用されないオブジェクトのリサイクルに最後に最善を尽くしたあとのメモリー使用量を返します。
    long
    このメモリー・プールのコレクション使用量しきい値(バイト単位)を返します。
    long
    メモリー使用量がコレクション使用量しきい値を超えたことをJava仮想マシンが検出した回数を返します。
    このメモリー・プールを管理しているメモリー・マネージャの名前を返します。
    このメモリー・プールを表す名前を返します。
    Java仮想マシンが起動されてから、またはピークがリセットされてからの、このメモリー・プールのピーク・メモリー使用量を返します。
    このメモリー・プールの型を返します。
    このメモリー・プールのメモリー使用量の評価値を返します。
    long
    このメモリー・プールの使用量しきい値をバイト単位で返します。
    long
    メモリー使用量がしきい値を超えた回数を返します。
    boolean
    Java仮想マシンが最善を尽くした最後のコレクションのあとに、このメモリー・プールのメモリー使用量がコレクション使用量しきい値に達した、または超えたかをテストします。
    boolean
    このメモリー・プールがコレクション使用量しきい値をサポートするかどうかをテストします。
    boolean
    このメモリー・プールのメモリー使用量が使用量しきい値に達した、または超えたかどうかをテストします。
    boolean
    このメモリー・プールが使用量しきい値をサポートするかどうかをテストします。
    boolean
    このメモリー・プールがJava仮想マシンで有効かどうかをテストします。
    void
    このメモリー・プールのピーク・メモリー使用量統計を現在のメモリー使用量にリセットします。
    void
    setCollectionUsageThreshold​(long threshold)
    このメモリー・プールのコレクション使用量しきい値を指定されたthreshold値に設定します。
    void
    setUsageThreshold​(long threshold)
    このメモリー・プールが使用量しきい値をサポートしている場合、このメモリー・プールのしきい値を指定されたthreshold値に設定します。

    インタフェース java.lang.management.PlatformManagedObjectで宣言されたメソッド

    getObjectName
  • メソッドの詳細

    • getName

      String getName()
      このメモリー・プールを表す名前を返します。
      戻り値:
      このメモリー・プールの名前
    • getType

      MemoryType getType()
      このメモリー・プールの型を返します。

      MBeanServerアクセス:
      MemoryTypeのマップ型はString、値はMemoryTypeの名前です。

      戻り値:
      このメモリー・プールの型
    • getUsage

      MemoryUsage getUsage()
      このメモリー・プールのメモリー使用量の評価値を返します。 このメソッドは、メモリー・プールが有効でない(存在しない)場合nullを返します。

      このメソッドは、このメモリー・プールの現在のメモリー使用量のベスト・エフォートの評価を行うようJava仮想マシンに要求します。 一部のメモリー・プールでは、このメソッドは評価値の判定にいくらかの計算を必要とする負荷の大きい操作になる可能性があります。 実装は、該当する状況をドキュメント化する必要があります。

      このメソッドは、システム・メモリー使用量の監視とメモリー不足条件の検出に使用するために設計されています。

      MBeanServerアクセス:
      MemoryUsageのマップ型は、MemoryUsageで指定された属性を含むCompositeDataです。

      戻り値:
      MemoryUsageオブジェクト。このプールが無効な場合はnull
    • getPeakUsage

      MemoryUsage getPeakUsage()
      Java仮想マシンが起動されてから、またはピークがリセットされてからの、このメモリー・プールのピーク・メモリー使用量を返します。 このメソッドは、メモリー・プールが有効でない(存在しない)場合nullを返します。

      MBeanServerアクセス:
      MemoryUsageのマップ型は、MemoryUsageで指定された属性を含むCompositeDataです。

      戻り値:
      ピーク・メモリー使用量を表すMemoryUsageオブジェクト。このプールが無効な場合はnull
    • resetPeakUsage

      void resetPeakUsage()
      このメモリー・プールのピーク・メモリー使用量統計を現在のメモリー使用量にリセットします。
      例外:
      SecurityException - セキュリティ・マネージャが存在する場合で、呼出し元がManagementPermission("control")を持たない場合。
    • isValid

      boolean isValid()
      このメモリー・プールがJava仮想マシンで有効かどうかをテストします。 Java仮想マシンがメモリー・システムからメモリー・プールを削除すると、メモリー・プールは無効になります。
      戻り値:
      実行されているJava仮想マシンでメモリー・プールが有効な場合はtrue、そうでない場合はfalse
    • getMemoryManagerNames

      String[] getMemoryManagerNames()
      このメモリー・プールを管理しているメモリー・マネージャの名前を返します。 各メモリー・プールは、少なくとも1つのメモリー・マネージャにより管理されます。
      戻り値:
      Stringオブジェクトの配列。各Stringオブジェクトは、このメモリー・プールを管理しているメモリー・マネージャの名前。
    • getUsageThreshold

      long getUsageThreshold()
      このメモリー・プールの使用量しきい値をバイト単位で返します。 各メモリー・プールは、プラットフォームに依存するデフォルトのしきい値を持ちます。 現在の使用量しきい値は、setUsageThresholdメソッドを使って変更できます。
      戻り値:
      このメモリー・プールの使用量しきい値(バイト単位)
      例外:
      UnsupportedOperationException - このメモリー・プールが使用量しきい値をサポートしない場合。
      関連項目:
      isUsageThresholdSupported()
    • setUsageThreshold

      void setUsageThreshold(long threshold)
      このメモリー・プールが使用量しきい値をサポートしている場合、このメモリー・プールのしきい値を指定されたthreshold値に設定します。 しきい値が正の値に設定されると、このメモリー・プールで使用量しきい値の超過チェックが有効になります。 しきい値がゼロに設定されると、このメモリー・プールで使用量しきい値の超過チェックが無効になります。
      パラメータ:
      threshold - バイト単位の新しいしきい値。 負でない数値。
      例外:
      IllegalArgumentException - thresholdが負の場合、またはこのメモリー・プールの使用可能メモリー量の最大値(定義されている場合)を超える場合。
      UnsupportedOperationException - このメモリー・プールが使用量しきい値をサポートしない場合。
      SecurityException - セキュリティ・マネージャが存在する場合で、呼出し元がManagementPermission("control")を持たない場合。
      関連項目:
      isUsageThresholdSupported(), 使用量しきい値
    • isUsageThresholdExceeded

      boolean isUsageThresholdExceeded()
      このメモリー・プールのメモリー使用量が使用量しきい値に達した、または超えたかどうかをテストします。
      戻り値:
      このメモリー・プールのメモリー使用量がしきい値に達したか、超えた場合はtrue、そうでない場合はfalse
      例外:
      UnsupportedOperationException - このメモリー・プールが使用量しきい値をサポートしない場合。
    • getUsageThresholdCount

      long getUsageThresholdCount()
      メモリー使用量がしきい値を超えた回数を返します。
      戻り値:
      メモリー使用量がしきい値を超えた回数
      例外:
      UnsupportedOperationException - このメモリー・プールが使用量しきい値をサポートしない場合。
    • isUsageThresholdSupported

      boolean isUsageThresholdSupported()
      このメモリー・プールが使用量しきい値をサポートするかどうかをテストします。
      戻り値:
      このメモリー・プールが使用量しきい値をサポートする場合はtrue、そうでない場合はfalse
    • getCollectionUsageThreshold

      long getCollectionUsageThreshold()
      このメモリー・プールのコレクション使用量しきい値(バイト単位)を返します。 デフォルト値は0です。 コレクション使用量しきい値は、setCollectionUsageThresholdメソッドを使って変更できます。
      戻り値:
      このメモリー・プールのコレクション使用量しきい値(バイト単位)
      例外:
      UnsupportedOperationException - このメモリー・プールがコレクション使用量しきい値をサポートしない場合。
      関連項目:
      isCollectionUsageThresholdSupported()
    • setCollectionUsageThreshold

      void setCollectionUsageThreshold(long threshold)
      このメモリー・プールのコレクション使用量しきい値を指定されたthreshold値に設定します。 このしきい値を正の値に設定すると、Java仮想マシンは、このメモリー・プールで使用されていないオブジェクトのリサイクルに最善を尽くしたあと、もっとも適した時期にメモリー使用量をチェックします。

      しきい値が正の値に設定されると、このメモリー・プールでコレクション使用量しきい値の超過チェックが有効になります。 しきい値がゼロに設定されると、このメモリー・プールでコレクション使用量しきい値の超過チェックが無効になります。

      パラメータ:
      threshold - 新しいコレクション使用量しきい値(バイト単位)。 負でない数値。
      例外:
      IllegalArgumentException - thresholdが負の場合、またはこのメモリー・プールの使用可能メモリー量の最大値(定義されている場合)を超える場合。
      UnsupportedOperationException - このメモリー・プールがコレクション使用量しきい値をサポートしない場合。
      SecurityException - セキュリティ・マネージャが存在する場合で、呼出し元がManagementPermission("control")を持たない場合。
      関連項目:
      isCollectionUsageThresholdSupported(), コレクション使用量しきい値
    • isCollectionUsageThresholdExceeded

      boolean isCollectionUsageThresholdExceeded()
      Java仮想マシンが最善を尽くした最後のコレクションのあとに、このメモリー・プールのメモリー使用量がコレクション使用量しきい値に達した、または超えたかをテストします。 このメソッドは、Java仮想マシンに、通常の自動メモリー管理以外のガベージ・コレクションを実行するよう要求しません。
      戻り値:
      このメモリー・プールのメモリー使用量が最後のコレクションでコレクション使用量しきい値に達したか、超えた場合はtrue、そうでない場合はfalse
      例外:
      UnsupportedOperationException - このメモリー・プールが使用量しきい値をサポートしない場合。
    • getCollectionUsageThresholdCount

      long getCollectionUsageThresholdCount()
      メモリー使用量がコレクション使用量しきい値を超えたことをJava仮想マシンが検出した回数を返します。
      戻り値:
      メモリー使用量がコレクションしきい値に達した、または超えた回数。
      例外:
      UnsupportedOperationException - このメモリー・プールがコレクション使用量しきい値をサポートしない場合。
      関連項目:
      isCollectionUsageThresholdSupported()
    • getCollectionUsage

      MemoryUsage getCollectionUsage()
      Java仮想マシンがこのメモリー・プールで使用されないオブジェクトのリサイクルに最後に最善を尽くしたあとのメモリー使用量を返します。 このメソッドは、Java仮想マシンに、通常の自動メモリー管理以外のガベージ・コレクションを実行するよう要求しません。 このメソッドは、Java仮想マシンがこのメソッドをサポートしない場合にnullを返します。

      MBeanServerアクセス:
      MemoryUsageのマップ型は、MemoryUsageで指定された属性を含むCompositeDataです。

      戻り値:
      Java仮想マシンが使用されないオブジェクトのリサイクルに最後に最善を尽くしたあとの、このメモリー・プールのメモリー使用量を表すMemoryUsage。このメソッドがサポートされていない場合はnull
    • isCollectionUsageThresholdSupported

      boolean isCollectionUsageThresholdSupported()
      このメモリー・プールがコレクション使用量しきい値をサポートするかどうかをテストします。
      戻り値:
      このメモリー・プールがコレクション使用量しきい値をサポートする場合はtrue、そうでない場合はfalse