JavaTM Platform
Standard Ed. 6

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() メソッドは、メモリープールの現在の使用量の見積もりを提供します。ガベージコレクトされたメモリープールの場合は、used メモリーの量にプール内のすべてのオブジェクト (到達できるオブジェクトおよび到達できないオブジェクトの両方を含む) によって占有されるメモリーが含まれます。  

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

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

Java 仮想マシンは、コレクション使用量しきい値チェックをメモリープールごとに実行します。

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

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

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

導入されたバージョン:
1.5
関連項目:
JMX 仕様。, MXBean にアクセスする方法

メソッドの概要
 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(), 使用量しきい値

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(), コレクション使用量しきい値

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 Platform
Standard Ed. 6

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

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