JavaTM 2 Platform
Standard Ed. 5.0

java.lang.management
インタフェース MemoryPoolMXBean


public interface MemoryPoolMXBean

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

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

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

java.lang:type=MemoryPool,name=pool's name

メモリの型

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

メモリ使用量の監視

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

1. メモリ使用量

getUsage() メソッドは、メモリプールの現在のおよその使用量を提供します。ガベージコレクトされたメモリプールの場合、使用されたメモリの量には、「到達可能な」オブジェクトと「到達不可能な」オブジェクトの両方を含む、メモリプールのすべてのオブジェクトが占めるメモリが含まれます。

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

2. ピークメモリ使用量

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

3. 使用量しきい値

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

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

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

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

  1. ポーリング

    アプリケーションでは、すべてのメモリプールに対して 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 つの getUsageThresholdCount() ポール間でしきい値以下であるかどうかを判定できます。

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

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

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

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

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

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

導入されたバージョン:
1.5
関連項目:
JMX Specification, Ways to Access MXBeans

メソッドの概要
 MemoryUsage getCollectionUsage()
          Java 仮想マシンがこのメモリプールで使用されないオブジェクトのリサイクルに最後に最善を尽くしたあとのメモリ使用量を返します。
 long getCollectionUsageThreshold()
          このメモリプールのコレクション使用量しきい値 (バイト単位) を返します。
 long getCollectionUsageThresholdCount()
          メモリ使用量がコレクション使用量しきい値を超えたことを Java 仮想マシンが検出した回数を返します。
 String[] getMemoryManagerNames()
          このメモリプールを管理しているメモリマネージャの名前を返します。
 String getName()
          このメモリプールを表す名前を返します。
 MemoryUsage getPeakUsage()
          Java 仮想マシンが起動されてから、またはピークがリセットされてからの、このメモリプールのピークメモリ使用量を返します。
 MemoryType getType()
          このメモリプールの型を返します。
 MemoryUsage getUsage()
          このメモリプールのメモリ使用量の評価値を返します。
 long getUsageThreshold()
          このメモリプールの使用量しきい値をバイト単位で返します。
 long getUsageThresholdCount()
          メモリ使用量がしきい値を超えた回数を返します。
 boolean isCollectionUsageThresholdExceeded()
          Java 仮想マシンが最善を尽くした最後のコレクションのあとに、このメモリプールのメモリ使用量がコレクション使用量しきい値に達した、または超えたかをテストします。
 boolean isCollectionUsageThresholdSupported()
          このメモリプールがコレクション使用量しきい値をサポートするかどうかをテストします。
 boolean isUsageThresholdExceeded()
          このメモリプールのメモリ使用量が使用量しきい値に達した、または超えたかどうかをテストします。
 boolean isUsageThresholdSupported()
          このメモリプールが使用量しきい値をサポートするかどうかをテストします。
 boolean isValid()
          このメモリプールが Java 仮想マシンで有効かどうかをテストします。
 void resetPeakUsage()
          このメモリプールのピークメモリ使用量統計を現在のメモリ使用量にリセットします。
 void setCollectionUsageThreshold(long threhsold)
          このメモリプールのコレクション使用量しきい値を指定された threshold 値に設定します。
 void setUsageThreshold(long threshold)
          このメモリプールが使用量しきい値をサポートしている場合、このメモリプールのしきい値を指定された threshold 値に設定します。
 

メソッドの詳細

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(), Usage threshold

isUsageThresholdExceeded

boolean isUsageThresholdExceeded()
このメモリプールのメモリ使用量が使用量しきい値に達した、または超えたかどうかをテストします。

戻り値:
このメモリプールのメモリ使用量がしきい値に達したか、超えた場合は true。そうでない場合は false
例外:
UnsupportedOperationException - このメモリプールが使用量しきい値をサポートしない場合

getUsageThresholdCount

long getUsageThresholdCount()
メモリ使用量がしきい値を超えた回数を返します。

戻り値:
メモリ使用量がしきい値を超えた回数
例外:
UnsupportedOperationException - このメモリプールが使用量しきい値をサポートしない場合

isUsageThresholdSupported

boolean isUsageThresholdSupported()
このメモリプールが使用量しきい値をサポートするかどうかをテストします。

戻り値:
このメモリプールが使用量しきい値をサポートする場合は true、そうでない場合は false

getCollectionUsageThreshold

long getCollectionUsageThreshold()
このメモリプールのコレクション使用量しきい値 (バイト単位) を返します。デフォルト値はゼロです。コレクション使用量しきい値は、setCollectionUsageThreshold メソッドを使って変更できます。

戻り値:
このメモリプールのコレクション使用量しきい値 (バイト単位)
例外:
UnsupportedOperationException - このメモリプールがコレクション使用量しきい値をサポートしない場合
関連項目:
isCollectionUsageThresholdSupported()

setCollectionUsageThreshold

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

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

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

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

JavaTM 2 Platform
Standard Ed. 5.0

バグの報告と機能のリクエスト
さらに詳しい API リファレンスおよび開発者ドキュメントについては、Java 2 SDK SE 開発者用ドキュメントを参照してください。開発者向けの詳細な解説、概念の概要、用語の定義、バグの回避策、およびコード実例が含まれています。

Copyright 2004 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Documentation Redistribution Policy も参照してください。