今週も先週に引き続きソフトウエアの保守に関する話題です。今週の主役はjconsoleです。

jconsoleはもともと簡易的な管理ツールとしてJ2SE 5.0から導入されたものです。簡易管理ツールとしての役割は同じですが,Java SE 6では,使いやすさが格段に向上しました。Java SE 6での変更点を,J2SE 5.0と比較していきましょう。

オンデマンドアタッチについては先週紹介しました。この機能はjconsoleの機能ではなく,Java VMの機能です。しかし,この機能によってjconsoleが使いやすくなったのは事実です。

jconsoleを起動すると,J2SE 5.0でもJava SE 6でも[概要]が表示されます。図1がJ2SE 5.0,図2がJava SE 6のスクリーンショットです。見れば一目瞭然,J2SE 5.0は文字で表示されていたものが,Java SE 6ではグラフ表示されています。

文字ではその時点での値しかわからないのに比べ,グラフにすることでトレンドを見ることができます。はっきりいえば,J2SE 5.0の[概要]は役立たずだったわけです。

Java SE 6 では[概要]だけでも十分な情報を得ることができるので,筆者はjconsoleを使う場合,[概要]のままにしておくことが多くなりました。

J2SE 5.0の[概要] Java SE 6の[概要]
図1 J2SE 5.0の[概要] 図2 Java SE 6の[概要]

上部のタブの順番も若干変更されています。[メモリ]などのタブで表示される情報はほとんど違いありません。しかし,[VMの概要]タブは表示される情報が変化しています。Java SE 6では,J2SE 5.0の[概要]タブと[VM]タブの情報を,[VMの概要]タブで一度に見られるようになっています。

J2SE 5.0の[VM] Java SE 6の[VMの概要]
図3 J2SE 5.0の[VM] 図4 Java SE 6の[VMの概要]

機能的に向上したのは,スレッドの間のデッドロックを検出できるようになったことです。[スレッド]タブの下部に[デッドロックを検出する]ボタンがあります。このボタンを押すと,デッドロックに陥ったスレッドを表示します。

Java SE 6の[デッドロックを検出する]ボタン
図5 Java SE 6の[デッドロックを検出する]ボタン

[MBean]タグも表示方法がずいぶん変更されました。J2SE 5.0ではタブが2重になっていたのが,Java SE 6では左側のツリー表示で[属性],[操作],[通知]が表示されるようになっています。どちらが好みかは人によりますが,筆者はJava SE 6のほうがすっきりしていると感じています。

J2SE 5.0の[MBean] Java SE 6の[MBean]
図6 J2SE 5.0の[VM] 図7 Java SE 6の[VMの概要]

ところで,図2の概要にはMXBeanから直接得られない情報が含まれています。右下のグラフで表示されているCPU使用状況です(図8)。

CPU使用状況
図8 CPU使用状況

MXBeanが拡張されたのかと思ってJavadocを調べてみても,CPU使用状況などはどこにもありません。

そこで,jconsoleのソースコードを調べてみました。Java SE 6はビルドが毎週公開されていますが,バイナリだけでなくソースコードもすべて公開されています。もちろん,jconsoleのソースコードもちゃんと含まれています。こういうときは,ソースコードがあるととても役に立ちますね。

問題の個所はsun.tools. jconsole.SummaryTabクラスにありました。

public void updateCPUInfo(Result result) {
  if (prevUpTime > 0L && result.upTime > prevUpTime) {
    // elapsedCpu is in ns and elapsedTime is in ms.
    long elapsedCpu = result.processCpuTime - prevProcessCpuTime;
    long elapsedTime = result.upTime - prevUpTime;
    // cpuUsage could go higher than 100% because elapsedTime
    // and elapsedCpu are not fetched simultaneously. Limit to
    // 99% to avoid Plotter showing a scale from 0% to 200%.
    float cpuUsage =
      Math.min(99F,
               elapsedCpu / (elapsedTime * 10000F * result.nCPUs));
  
    getPlotter().addValues(result.timeStamp, Math.round(cpuUsage));
    getInfoLabel().setText(getText(cpuUsageFormat, 
                           String.format("%2f", cpuUsage)));
  }
  this.prevUpTime = result.upTime;
  this.prevProcessCpuTime = result.processCpuTime;
}

updateCPUInfoメソッドのResultオブジェクトはMXBeanとのデータの受け渡しに使うクラスのようです。このメソッドを見ると,CPU使用量はOperatingSystemMXBeanから取得できるプロセスタイムと,RuntimeMXBeanから取得できるアップタイムから求めているに過ぎないようです。

概算値でしかありませんが,有用な情報であるのは確かですよ。

もしjconsoleを使ったことがないのでしたら,この機会にぜひ使ってみてください。

著者紹介 櫻庭祐一

横河電機 ネットワーク開発センタ所属。Java in the Box 主筆

今月の櫻庭

秋ですねぇ。秋といえばやっぱり栗。洋栗もいいですが,和栗もおいしい。ナポリの栗を使ったSadaharu AOKIのマロニエ・オ・ショコラや,ラ・プレシューズの和栗のモンブランなど,おいしい栗のお菓子がいろいろ。

その中でも櫻庭がお勧めなのはピエール・エルメのマカロン マロン エ テベール マッチャ 。マロンのマカロンに,抹茶のクリーム。そして,クリームの中にはマロングラッセが入っています。抹茶とマロングラッセという組み合わせは絶妙です。

と,今日もまた体重を気にしつつ,プログラミングしています。