|
JVM をかいま見る
|
||||
|
||||
JVM がどのような状態にあるかを調べることはアプリケーションには非常に重要です。 開発中であればメモリリークはないか、スレッドがデッドロックしていないかなどを調べることは不可欠です。運用中であってもメモリの使用量や CPU の使用量、スレッドの状態をモニタリングすることでアプリケーションが正常に動作しているか調べることができます。 実をいうと Tiger 以前でも、一般的にプロファイラと呼ばれるアプリケーションを使用することで JVM の状態を調べることは可能でした。市販の製品では Borland の Optimizeit や Quest Software の JProbe (日本での扱いは Tangent Computing もしくは グレープシティ) などがあります。フリーのものであれば、Eclipse Profiler Project や JMP などがあります。 これらのプロファイラを使えばとても詳しく JVM の状態をモニタリングすることができます。 しかし、問題があります。 プロファイルを一度使用されてみればすぐ分かるのですが、非常に重い。プロファイルを行っているせいで、アプリケーションの動作速度が非常に遅くなってしまうのです。 シングルスレッドのアプリケーションであればそれでもいいかもしれませんが、通信を行っていたり、マルチスレッドで動作のタイミングが重要なアプリケーションなどはプロファイリングを行っているせいで動作しなくなってしまうこともあります。 プロファイリングは非常に重要な機能でこれはこれで必要なのですが、もう少し機能を絞ってもいいのでもっと軽く JVM の様子をモニタリングするための機能がほしいところです。 そして、Tiger でその願いがやっとかなうことができました。それが JSR-174 で策定されている Monitoring and Management Specification for the Java Virtual Machine なのです。 JSR-174 は JMX をベースにしたフレームワークで、使い方は非常に簡単です。JVM の状態は MBean に保持されています。JMX をベースにしているということでローカルはもちろんリモートから JVM の状態を知ることもできます。 この機能を使用することで、サーバ系のアプリケーションの状態をリモートから調べるなんてこともできるのです。 まさに願っていた機能ではないでしょうか。
|
|
|||||||||||||||||||||||||||||||||||
Monitoring and Management for Java Platform で提供されている MBean は 9 種類あります。java.util.logging.LoggingMXBean 以外は java.lang.management パッケージで定義されています。
これらの MBean は単一のオブジェクトで自分で生成することはできません。MBean の取得には java.lang.ManagementFactory を使用します。 たとえば、RuntimeMXBean を取得するには次のようにします。
ManagementFactory クラスには static な MBean の取得メソッドが定義されています。
このメソッドを使用した場合は、MBeanServer オブジェクトには登録されていません。ローカルで使用するならばこのメソッドで取得できた RuntimeMBean オブジェクトをそのまま使用してもいいのですが、やはり MBeanServer オブジェクトに登録してリモートからでも見れるようにしてみましょう。 登録するには MBean の名前が必要なのですが、名前は ManagementFactory クラスの定数としてすでに定義されているのでそれを使用するようにします。
RUNTIME_MXBEAN_NAME は具体的には java.lang:type=Runtime となっています。したがって、ドメインは java.lang です。他の java.lang.management パッケージで提供されている MBean のドメインは java.lang となっています。 これを実行してブラウザで確認してみましょう。
RuntimeMXBean が登録されていることが確認できます。 このように 1 つ 1 つ MBean を取得して MBeanServer オブジェクトに登録してもいいのですが、ちょっと面倒です。だからというわけではないと思いますが、ManagementFactory#getPlatformMBeanServer メソッドという便利なメソッドが用意されています。 このメソッドを使ったサンプルが JVMMonitoringTest クラスです。
使い方はむちゃくちゃ簡単で、単にコールするだけでおしまいです。
getPlatformMBeanServer メソッドの戻り値は MBeanServer オブジェクトですでに java.lang.management パッケージで定義されている MBean がすべて登録されています。 これを実行してみたのが、図 2 です。
ずらっと MBean が並んでいるのを見ると壮観ですね。このように Monitoring and Management for Java Platform で定義された MBean を使用することはとても簡単です。 次章では、それぞれの MBean がどのような属性やオペレーション、ノティフィケーションを定義しているか 1 つ 1 つ確認していきましょう。
|
|
||||||||||||||||||||||||||||||||||||||||||||
まずはプラットフォームに関連する MBean から見ていきます。 OperatingSystemMXBeanOperatingSystemMBean では次の情報を参照することができます。
ところが、ブラウザで見てみるとこれ以外の情報も参照することができます。調べてみると、java.lang.management.OperatingSystemMBean インタフェースを派生させた com.sun.management.OperatingSystemMBean インタフェースを使用しているようです。 追加された情報は
ただし、ここで追加された情報はあくまでも Sun の HotSpot インプリメンテーションにおけるものなので、他社の Tiger に準拠した JavaVM でこれらの情報を参照できる保証はありません。
図 3 からはアーキテクチャが x86、OS が Windows XP でバージョンが 5.1 であることが分かります。使用したマシンはメモリが 768 MB、スワップ用に 372 MB とってあるので、図 3 の値とだいたい一致しますね。数値が一致していないのは、この PC がメインメモリの一部をグラフィックメモリとして使用しているからです。
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
次はアプリケーションの実行環境に関する MBean です。 RuntimeMXBeanRuntimeMXBean はアプリケーションの実行時の環境に関する情報を提供します。参照できる情報は
システムプロパティの型は Map<String, String> なのですが、HTML プロトコルアダプタだと TabularData とあらわされてしまいます。この TabularData は javax.management.openmbean パッケージで OpenMBean で使用されるインタフェースなのですが、これを派生させている TabularDataSupport クラスは Map インタフェースもインプリメントしているのでこのように表示されるのでしょう。 また、起動時オプションは JVM のオプションで main メソッドの引数 args ではないようです。こちらも型は List<String> なのですが、String[] になってしまっています。
モザイクがかかっていているのは、マシン固有のパスとかが入っているからです。普通に見たらもちろんちゃんと見えますよ。
CompilationMXBeanJIT に関する情報を保持する MBean です。閲覧できるのは
ClassLoadingMXBeanClassLoadingMXBean はクラスロードに関する情報を保持しています。
verbose は起動時オプションの -verbose:class が指定されているかどうかを示しています。この属性は書きこみ可なので、途中から verbose をオンにすることもできます。
ロードされているクラスは 173 で、アンロードされたクラスはありません。ロードされているクラスが以外に少ないと思いませんか。そんなもんなのかな。
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
スレッドに関する情報を扱うのは ThreadMXBean だけですが、かなりたくさんの情報を見ることができます。 ThreadMXBeanThreadMBean を使用すれば、アプリケーションで動作しているすべてのスレッドの情報を見ることができます。 ThreadMBean の属性を次に示します。
スレッドの CPU 時間とユーザ時間はナノ秒単位なのですが、その正確性は OS やプラットフォームに依存するようです。たまたまこのときのカレントスレッドは 0 ナノ秒になっています。 次はオペレーションです。
getThreadInfo オペレーションの戻り値は ThreadInfo クラスです。このクラスはスレッドのさまざまな情報を保持しています。
getThreadState オペレーションの戻り値は Thread クラスの内部 enum の Thread.State になります。Thread.State は次の状態を示すことができます。
残念ながら HTML プロトコルアダプタは ThreadInfo クラスをサポートしていないのでブラウザではこれらの情報を見ることができません。そこで、次のようなサンプルを作ってみました。
ThreadMBean オブジェクトから現在存在しているすべてのスレッドに関する ThreadInfo オブジェクトを取得し、これを GUI で表示するというサンプルです。 ThreadInfo オブジェクトは getThreadInfo(long[] ids, int maxDepth) メソッドを使用して、まとめて取得してもいいのですが、CPU 時間が ThradInfo オブジェクトに含まれないので、次のようにループして取得するようにしました。 スタックトレースは 5 行分取得するようにしています。
addInfoTab メソッドでスレッドの情報を表示するのですが、画面を構成しているのは addInfoTab メソッドからコールされる updateInfoTab メソッドです。updateInfoTab メソッドではまずスレッドの情報を取得し、それを JLabel クラスを使用して画面に表記しています。
このように synchronized ブロックを使用しているのは、ThreadInfo オブジェクトに対応してスレッドが終了してしまうと ThreadInfo オブジェクトも消滅してしまう null になってしまうことがあるためです。 実行すると次のようなフレームが描画されます。
これを見ていると、いろいろと興味深いです。たとえば、AWT-Windows スレッドはネイティブコードで実行されているとか。WAITING 状態にあるスレッドと RUNNNIG 状態にあるスレッドなど、など。 Update ボタンで情報を更新できるので、更新すると main スレッドが終了していることが分かります。その他、いろいろ発見があるかもしれません。
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
最後に残ったのが一番の大物、メモリに関する MBean です。メモリに関する MBean には MemoryMXBean, MemoryPoolMXBean, MemoryManagerMXBean, GarbageCollectorMXBean と 4 種類もあります。 メモリに関する MBean を試す前に現在の HotSpot におけるメモリマネージメントを少しだけおさらいしておきます。 HotSpot のメモリマネージメントJVM が使用するメモリ領域にはヒープ領域とノンヒープ領域に分けることができます。すべてのオブジェクトはヒープ領域にアロケートされます。ノンヒープ領域は Java Virtual Machine Specification では Method 領域と呼ばれていますが、コンスタントプールやメソッドテーブルなどクラスごとにあるデータを配置します。 それぞれの領域のサイズは固定ではなく、増減することが可能です。
ヒープ領域にはオブジェクトがアロケートされますが、アロケートする領域が不足した場合 Garbage Collection を行い不要なオブジェクトを廃棄します。 HotSpot はこの GC の手法として Generational GC を採用しています。この手法はオブジェクトの寿命 (オブジェクトが生成されてから消滅するまでの期間) に着目したものです。Generation GC ではヒープを世代ごとに次に示す 2 つの領域に分割しています。
ノンヒープ領域はこの Generation にたとえて Permanent Generation と呼ばれます。 オブジェクトが生成されるとまず Young Generation にアロケートされます。Young Generation に新たにオブジェクトをアロケートする領域がなくなると、Young Generation だけを対象にした GC が行われます。 GC を何度も生き抜いたオブジェクトは寿命が長いとみなされるので Young Generation から Old Generation にコピーされます。 Old Generation にコピーされたオブジェクトも使われなくなることがあります。また、新たに Young Generation からオブジェクトがコピーされきます。このようなオブジェクトが溜まってきてしきい値を超えると、Young/Old を問わずすべての領域を対象にした GC が行われます。 java のオプションで -verbose:gc をつけると GC が行われる様子が分かります。[GC 837K->353K(1984K), 0.0015108 secs] と表記されるものが Young Generation を対象とした GC を表しており、[Full GC 513K->276K(1984K), 0.5010827 secs] と表記されたときがすべての領域を対象に GC が行われたことを表しています (もちろん、メモリのサイズや時間は毎回異なります)。 これが基本なのですが、HotSpot では効率化のために Young Generation をさらに Eden, Survivor 1, Survivor 2 と呼ばれる 3 つの領域に分割しています。Old Generation は 1 つのままですが Tenured と呼ばれるようです。 オブジェクトが最初にアロケートされるのが Eden です。GC が行われると Eden にあるオブジェクトは Suvivor 1 にコピーされます。このとき Survivor 2 は使用されません。この GC で Eden は空になります。 次の GC では Eden と Survivor 1 のオブジェクトが Survivor 2 にコピーされます。このコピーで Eden と Survivor 1 は空になります。 このように Survivor を交互に使用するのがこの方法の特徴です。Eden も Survivor も 1 度の GC で空になりことから、効率よく高速に行うことが可能です。 Old Generation の GC には Mostly Concurrent Mark & Sweep 方式が使用されますが、ここでは省略します。詳しくは ISMM 2000 で発表された A Generational Mostly-concurrent Garbage Collector をご覧ください。
MemoryMXBean本題に戻りましょう。まずはメモリに関して一番基本となる MemoryMXBean からです。MemoryMXBean を使用することでヒープ領域とノンヒープ領域の使用状況を調べることが可能です。
Verbose だけが書き込み可能なので、後から verbose を設定することも可能です。 MemoryMBean で定義されているオペレーションには gc があります。名前のとおり GC を行うものです。
属性の HepMemoryUsage と NonHeapMemoryUsage がメモリ領域の使用状況を表すものです。メモリの使用状況には MemoryUsage クラスを使用してます。 MemoryUsage クラスには 4 つの属性があり、単位はすべてバイトです。
残念ながら MemoryUsage クラスは HTML プロトコルアダプタでサポートしていない型なので、次のようなサンプルを作ってみました (ただし、HTML プロトコルアダプタでも MemoryUsage#toString メソッドを使用しているので属性の値を見ることは可能です)。
500ms ごとに HeapMemoryUsage と NonHeapMemoryUsage を取得してメモリの使用量をグラフに表示します。500ms ごとにコールされるのが MemoryMXBeanTest#updateView メソッドです。heapGraph と nonheapGraph は MemoryUsageGraph オブジェクトです。
表示の中にある数字は左から max, committed, used の順です。この表示は -Xmx4m というオプションで起動させています。-Xmx はヒープの最大を決めるためのオプションなのですが、なぜかヒープの最大は 3.94 MB。なぜなんでしょう。
MemoryPoolMXBeanMemoryMXBean を使えば、ヒープとノンヒープという 2 つの領域の情報を得られることが分かりました。しかし、前述したようにこれらのメモリ領域はいくつかのサブ領域に分割されて使用されています。これらの領域がメモリプールですが、その状況を見るために使用されるのが MemoryPoolMXBean です。 MemoryPoolMXBean で定義されている属性を次に示します。
メモリの使用状況に関して Usage というのと CollectionUsage というのがあるのがお分かりだと思います。この 2 つの違いは Usage が現在のメモリ使用状況なのに対し、CollectionUsage は GC が終わったあとのメモリ使用量ということです。 それぞれしきい値 (UsageThreshold もしくは CollectionUsageThreshold) を設定することができます。これを使えば、しきい値を超えているかどうか、また超えた回数などを調べることができます。 MemoryPoolMBean で定義されているオペレーションを次に示します。
Tiger では Young Generation で 3 メモリプール、Old Generation で 1 メモリプール、Permanent Generation で 4 つのメモリプールがあります。それぞれのメモリプールの情報を調べるために次のようなサンプルを作ってみました。
やっていることは ThreadMXBeanTest クラスとあまり変わりません。MemoryPoolMXBean から情報を取得して GUI で描画しているだけです。
beta 1 では Survivor 領域はちゃんと 2 つとして認識されていたのですが、beta 2 では 1 つとして数えられているようです。まぁ、一方を使っているときは、もう一方は空なので 1 つでいいのかもしれません。 なぜかよく分からないのですが、Eden は UsageThreasholdSupported が false になっています。たしかに Eden にしきい値をつける必要は全然ないと思いますが、よく分かりません。 このように UsageThresholdSupported や CollectionUsageSupported が false になる場合、UsageThresholdExceeded と UsageThresholdCount などの属性を取得しようとすると例外が発生してしまうので、注意が必要です。
MemoryManagerMXBean, GarbageCollectorMXBeanMemoryManagerMXBean はメモリプールの管理情報に関する MBean です。GarbageCollector もメモリを管理しているので、GarbageCollectorMXBean は MemoryManagerMXBean の派生インタフェースとなっています。 MemoryManagerMXBean だけではあまり面白くないので、ここでは GarbageCollectorMXBean を取りあげましょう。 GarbageCollectorMXBean で定義されている属性を次に示します。
これ以外に MemoryManagerMXBean で定義されている属性もあります。
ところが GarbageCollectorMXBean も OperatingSystemMXBean のように拡張されているようです。実際には com.sun.management.GarbageCollectorMXBean が使用されています。ここで定義されている属性は次のようなものがあります。
LastGCInfo の型である GCInfo クラスはやはり com.sun.management パッケージにあります。GCInfo クラスには次に示すメソッドが用意されています。
GCInfo クラスを扱えるようなサンプルということで今までほとんど同じですが、GarbageCollectorMXBeanTest クラスを作ってみました。
実行結果を図 13 に示します。
このぐらいの小さいアプリケーションだと Mark & Sweep の GC はなかなか発生しないので、強引に GC をさせるために GC ボタンをつけてあります。この GC ボタンがクリックされると MemoryMXBean#gc メソッドをコールするようにしてあります。
メモリに関するノティフィケーションメモリの使用量はアプリケーションを書くときに気になるところです。予想外にメモリ使用量が多かったり、メモリリークが起こっていたりしたらと思うと気が気ではありません。 そんなあなたに効果的なのがノティフィケーションです。JSR-174 で定義されているノティフィケーションは 2 つあり、両方ともメモリに関するものです。
MemoryPoolMBean の属性に UsageThreashold と CollectionUsageThreshold というのがありましたが、これがノティフィケーションの発生にかかわってくるしきい値になります。 UsageThreshold を超えた場合、1 のノティフィケーション。CollectionUsageThreshold を超えた場合、2 のノティフィケーションになります。 こう聞くと、 リスナ登録をするのは MemoryPoolMBean のような気がしますが、実際には MemoryMBean になります。メモリに関するものは MemoryMBean でまとめて扱おうということなのだと思います。 さて、ノティフィケーションを扱うサンプルを作ってみましょう。先ほどの、MemoryPoolMBeanTest クラスを拡張してノティフィケーションを扱えるようにしてみます。
メモリに関するノティフィケーションは通常の Notification クラスを使用します。メモリに関する情報を引っ張り出すには Notification#getUserData メソッドを使用します。 リスナ登録は MemoryNotificationTest クラスのコンストラクタで行っているので、その部分の抜きだしてみましょう。
ノティフィケーションが発生したら、Notification#getType メソッドでそのノティフィケーションが何かを調べます。メモリに関するノティフィケーションは MemoryNotificationInfo クラスで定義されている MEMORY_THRESHOLD_EXCEED か MEMORY_COLLECTION_THRESHOLD_EXCEEDED になります。 Notification#getUserData メソッドの戻り値は Object クラスなのですが、上記の 2 つのタイプの場合は javax.management.openmbean.CompositeData クラスになります。CompositeData クラスは複合データ用の汎用クラスなので、そのままだと少し使いにくいのです。 そこで、メモリに関するノティフィケーションに特化した java.lang.management.MemoryNotificationInfo クラスを使用します。CompositeData クラスから MemoryNotificationInfo クラスに変換するには、static な from メソッドを使用します。 MemoryNotificationInfo クラスは次のような情報を保持しています。
上記のコードではプール名と使用状況をダイアログで出力しています。 リスナ登録を行うには MemoryMXBean オブジェクトを NotificationEmitter オブジェクトにキャストしてから行います。 MemoryNotificationTest クラスを実行するには、引数が 2 つ必要です。第 1 引数が UsageThreshold、第 2 引数が CollectionUsageThreshold になります。両方とも Tenured Gen に設定しました。
ノティフィケーションが発生した時は図 14 のようになります。このときは CollectionUsageThreshold を 1MB に設定して実行させたところです。
|
|
||||||||||||||||||||||||
最後に残ったのがちょっと毛色の変わったロギングに関する MBean である LoggingMXBean です。この MBean だけ java.util.logging パッケージで定義されています。
view the values o LoggerNames をクリックしてみると次のようになりました。
LoggingMXBean にはオペレーションは次の 3 つが定義されています。
この MBean を使えば、アプリケーションを動作中にロガーのレベルを帰ることができるので、運用開始時はレベルを下げておいて、問題なかったらレベルを上げるなんてことが可能になります。 でも、もっとカスタマイズできるといいと思うのは私だけではないと思うのですが。特にハンドラーに関する属性やオペレーションなどがあればいいと思います。たとえば、ハンドラーのレベルを変えたり、後からハンドラーを追加したりしたりできたらいいと思いませんか。
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
今までの例はすべてアプリケーションのコードの中に MBean を作成、登録するコードを書いていました。しかし、既存のアプリケーションを管理したい場合はどうしましょう。 Monitoring and Management for Java Platform にはそれに対する解も提供しているのです。 やり方は簡単で、起動オプションをちょっと加えるだけなのです。 ローカルでの管理まずはローカルのマシンでやってみましょう。とはいっても同じ JVM 上で管理するわけではなく、アプリケーションと管理アプリケーションは別々のプロセスとして起動します。 管理するアプリケーションはトリビアアプリケーション、管理アプリケーションには J2SDK に付属する jconsole を使用します。 管理するためには java の起動オプションとして -Dcom.sun.management.jmxremote をつけて起動します。
2 行になってしまっていますが、実際には 1 行で入力しています。 起動したら、他のコンソールから jps コマンドを起動します。このコマンドは起動している JVM の pid を出力します。この中から TriviaServer の pid を探し出して、その値を jconsole コマンドの引数にします。
jconsole を起動すると図 17 のようなウィンドウが表示されます。
jconsole は Monitoring and Management for Java Platform に特化しているので、他の MBean は見ることはできません。でも、HTML プロトコルアダプタで見るよりはずっと使いやすいインタフェースになっています。 気をつけなくてはいけないことは、ローカルで jconsole を使うときアプリケーションと同じユーザアカウントで行う必要があることです。
RMI を使用したリモートでの管理JMX Remote を使用すればリモートから RMI を使用してアプリケーションの管理ができます。Monitoring and Management for Java Platform でも RMI のコネクタを使用できるので、リモートから管理を行うことができます。 RMI を使って管理するためには java の起動オプションとして -Dcom.sun.management.jmxremote.port=[ポート番号] をつけて起動します。デフォルトでは SSL が使用されるので、SSL を使用しない場合には -Dcom.sun.management.jmxremote.ssl=false オプションも付加します。 下の例ではポート 8000 を使用した例です。起動すると RMI コネクタを起動したというログがコンソールに出力されます。
ここで出力されている URL でリモートからアクセスするようにします。サーバの名前は jmxr に固定されてしまうようです。 jconsole ではこのデフォルトの名前が分かっているため ホストネーム:ポート でアクセスできます。
そうすると先ほどと同じウィンドウが表示されるはずです。 ここでは SSL を使用しないことを直接オプションで記述しましたが、設定ファイルで設定する方法もあります。設定ファイルを読み込むには次のオプションを指定します。 -Dcom.sun.management.config.file=[設定ファイルのパス] デフォルトでは jre/lib/management/management.properties が使用されます。 その他にもパスワードなどオプションがあるのですが、詳しくは Out-of-the-Box Remote Monitoring and Management のドキュメントをご覧ください。 また、jconsole や jps などのツールに関しては Tools and Utilities のドキュメント をご参照ください。
SNMP を使用したリモートでの管理なんと Tiger では SNMP プロトコルアダプターも標準で使えるようになっています。 ただし、パッケージは com.sun.jmx.snmp なので標準というわけではありません。また、ドキュメントも Monitoring and Management for Java Platform に関する部分しかないので、自由にアプリケーションの中で使うというわけにはいかなそうです。 SNMP で管理をする場合も SNMP コネクタを起動するポートを指定するだけです。 -Dcom.sun.management.snmp.port=[ポート番号] 通常 SNMP では 161 が使われます。SNMP での設定ファイルの指定は RMI と同じです。デフォルトの設定ファイルも jre/lib/management/management.properties が使用されます。 また、コミュニティなどを記述した ACL (Access Control List) ファイルを指定する場合は -Dcom.sun.management.snmp.acl.file=[ACL ファイルのパス] ACL がよく分からない場合は、ACL を無効にしてしまうこともできます。 -Dcom.sun.management.snmp.acl=false ただし、このオプションを指定した場合はどこからでもアクセスできてしまうので、テストの時以外は使わないほうがいいと思います。 さて、SNMP でアクセスするには oid が必要です。oid が分からなければどこにもアクセスできません。まずはどんな oid があるか調べるために、net-snmp を使ってすべての oid を取得してみました。実行は Fedora Core 1 で行っています。
詳しい MIB の定義は JVM-MANAGEMENT-MIB.mib に記載されているのですが、oid の名前と型を抜粋したのが下の表です。どの oid が、どの MBean の属性に対応するかはだいたい名前からお分かりだと思うので記述しませんでした。 もしかしたら抜けや間違いがあるかもしれませんが、もし見つけたらご連絡ください。
|
|
||||
Monitoring and Management for Java Platform はこれを記述している時点では、まだまだ仕様が確定していないようです。alpha の時には影も形もなく、beta 1 になって登場し、beta 2 でクラス名をはじめかなりの部分が変更されています。 J2SE 1.4 の時の Logging API がこんな感じでした。書いても書いてもまた修正しなくてはならなかったのを思いだします。できれば、Monitoring and Management for Java Platform ではそんなことがないようにしてもらいたいものですが、どうなることやら。 仕様変更に関してはともかく、便利であることは間違いありません。 私が愛用しているツールの 1 つに jvmstat というのがあります。このツールを使うとメモリの詳細が分かるのです。残念なことにこのツールは J2SE 1.4 専用なのです。 しかし、Monitoring and Management for Java Platform を使えば jvmstat のようなものはすぐ作れてしまうのです。J2SDK には jconsole というツールも付属しています。また、MC4J のように Tiger に対応した JMX 管理アプリケーションも出てきています。 いつでもどこでも好きなように JVM の中を覗けるなんて、なんてすばらしいんでしょう。
今回使用したサンプルはここからダウンロードできます。
参考
(Jun. 2004) |
|