Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

今日から始めるHotRockit

こんにちは、せろ ( id:cero-t ) です。
ちょっと今日はこっちのAcroquestエンジニアblogに出張投稿します。


Javaエンジニアの皆様方におかれましては、
HotRockitの登場を、今か今かと待ちかねていることと思いますが、、、
えっ、
ご存知ない?


HotRockitとは、旧SunのHotSpot JavaVMに、
旧BEAのJRockit JavaVMの機能を統合するというプロジェクトです。
テクニカルな面は、Oracleのスライドが分かりやすいですね。
http://www.slideshare.net/OracleMiddleJP/project-hotrockit


私も、HotRockitを見据えて、HotSpotとJRockitのツールについてコラムを書きました。
http://www.acroquest.co.jp/webworkshop/JavaTroubleshooting/column_006Main.html
このコラムでも触れていますが、普段使っているJavaVMがHotRockitになることで
HotSpotとJRockitの両方の解析ツールが使えるということが、大きなメリットの一つです。


そんなHotRockitは今年登場する予定だそうですが、
実は、
もう既にその片鱗は見えているのです。


今日はそれを実際に使ってみよう、というお話です。

実はJava7 update4に入っているHotRockit。

昨年の4月に、Java7のupdate4が公開されました。
http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html


このアップデートではMac版が正式リリースされたこともあり、
世の中的には(私のTwitterタイムラインでは)そちらの注目の方が大きかったのですが
その影で、こっそりHotRockitの成果物が公開されていたのです。


先のプレスリリースを良く見てみましょう。

Diagnostics command framework (jcmd) and diagnostic commands

Java SE 7 Update 4 Release Notes - Oracle

これだけです。分かるかっ!


このjcmdコマンドこそJRockit由来のコマンドであり、
これがHotSpotなJavaSE7 update4から使えるようになった、というわけです。


ちなみにJRockitのアーキテクトであるMarcus Hirtのblogでは、
しっかり紹介されていました。

JDK7 was quite recently released, and I thought I should mention a few new cool things in it.
First out is the port of the small JRockit command line utility JRCMD (JRockit Command).
(略)
The second big feature is the first port of the JRockit Flight Recorder - a high performance event recorder built into the JVM.

Marcus Hirt's Private Blog

HotRockitの最新情報は、このblogを見るのが一番早いですね。

ついにMacでFlightRecording。

先に書いたように、Java7 update4はMacでも使えるのですから、
これまでWindowsでしか使えなかったJRockitのコマンド群が、
Macで使えるようになったわけです。
特に「これまで使えなかった」という点では、FlightRecorderの存在が大きいでしょう。


FlightRecorderは、JRockitに付属しているトラブルシュートツールのひとつで、
Javaの挙動を記録し続け、障害発生時などにダンプ出力することができるものです。


JRockitはMac版が用意されていなかったため、
これまでMacではFlightRecorderを利用する手段がありませんでした。
しかし、HotRockit(Java7 update4以降)にはMac版が用意されているため、
やっとFlightRecorderが使えるようになったわけです。


今回は、このFlightRecorderを実際に動かしてみましょう。
こんな感じの画面が出すところがゴールです。


ただ先に書いておきますが、
FlightRecorderはJava7 update10の時点では、全く情報を取ることができません。
今年の4月頃に出る予定のJava7 update12から情報が取れるそうですので
あくまでも、今回は雰囲気を味わう程度だと思って楽しんでください。

FlightRecorderが動くまで

Flight Recorderは、
 ・解析対象アプリケーション(FlightRecorder適用済み)
 ・FlightRecorderの情報を閲覧するためのクライアント(Mission Control)
という、2プロセスを使った構成になりますので
それぞれのセットアップが必要です。


大きな流れとしては、以下のようになります。
 1. Java7(update4以降)のセットアップ
 2. Mission Controlのインストール(FlightRecorderの記録閲覧用)
 3. 解析対象アプリケーションの実行(FlightRecorderを有効にする起動引数つき)
 4. FlightRecorderの起動(jcmdコマンド)
 5. FlightRecorderの結果をMissionControlで閲覧


FlightRecorderはMission Control側からも操作できるはずなのですが、
Java7 update10時点ではまだそのような連携ができないため、
jcmdコマンドを使ったFlightRecorderの記録や、閲覧記録の取得を行ないます。


それでは、順に説明しましょう。

1. Java7のセットアップ

http://www.oracle.com/technetwork/java/javase/downloads/index.html
まずはここからJDK7の最新版をダウンロードして、
さくっとインストールして、パスを通してください。


それが終わったら、早速、コマンドの確認です。

$ javac -version
javac 1.7.0_07

私のMacにはJava7 update7が入っているので、こんな表示です。


では、JRockit由来のコマンドであるjcmdを実行してみましょう。
初めてなのでドキドキする瞬間です。

$ jcmd
18128 sun.tools.jcmd.JCmd

出ました!
jcmdコマンドを引数指定なしで実行すると、現在実行中のJavaVMの一覧が表示されます。
HotSpotに付属のjpsコマンドと同じですね。
ちなみに上の例では、実行したjcmdコマンド自体のプロセスだけが表示されています。

2. Mission Controlのセットアップ

続いて、Mission Controlをインストールしましょう。
WindowsであればJRockit自体をインストールすれば、
Mission Controlも一緒にインストールされます(bin/jrmc.exeがそれです)


しかしMacにはJRockitが提供されていないため、
今回はEclipseプラグイン版のMission Controlを利用します。
Eclipse 3.7 (indigo) をインストールし、update siteを利用してインストールします。

http://download.oracle.com/technology/products/missioncontrol/updatesites/base/4.1.0/eclipse/

インストール完了後、メニューから[Window] - [Open Perspective] - [Other]を選んで
「Mission Control」のパースペクティブが表示されていれば、インストール成功です。

3. 解析対象アプリケーションの実行

続いて、FlightRecorderを適用して、解析対象のアプリケーションを実行しましょう。


今回は、みんな大好き(?)Tomcatを使います。
http://tomcat.apache.org/download-70.cgi
この辺りから、Tomcatをダウンロードして解凍してください。


ところで、FlightRecorderを動かすためには、
Javaの起動引数で、FlightRecorderを有効化するオプションを指定する必要があります。

  • XX:+UnlockCommercialFeatures -XX:+FlightRecorder


Tomcatの起動スクリプトの中で、このオプションを指定するように修正しましょう。
Macなら、Tomcatのホームディレクトリのbin/startup.shに以下の一行を追加します。

export JAVA_OPTS="-XX:+UnlockCommercialFeatures -XX:+FlightRecorder"


Windowsなら、bin/startup.batの最初のほうに以下の一行を追加します。

set JAVA_OPTS=-XX:+UnlockCommercialFeatures -XX:+FlightRecorder


これを指定してから、startup.shなりstartup.batなりを実行して、Tomcatを起動しましょう。
Tomcatが起動したら、またjcmdコマンドを実行してみましょう。

$ jcmd
18519 org.apache.catalina.startup.Bootstrap start
18525 sun.tools.jcmd.JCmd

Bootstrapという表示がある方がTomcatのプロセスですね。
このプロセスで利用できるjcmdコマンド一覧を確認してみましょう。

jcmd 18519 help
18519:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.commercial_features
ManagementAgent.stop
ManagementAgent.start_local
...

このようにコマンド一覧が表示され、特にJFR.で始まる4つが表示されれば成功です。


ここで、もしTomcatが古いバージョンのJavaで起動されていた場合には、
以下のようなエラーが出てしまいます。

java.io.IOException: Command failed in target VM

その場合には、環境変数かstartup.sh (startup.bat) で
JAVA_HOMEにJava7のホームディレクトリを指定してください。


また、JFR.で始まるコマンドが見えず、他のコマンドしか表示されない場合には
FlightRecorderを有効にする起動引数が正しく指定されていない可能性があります。
起動引数の内容や指定場所を、きちんと確認してください。

4. FlighRecorderの起動

JFR.コマンドが有効化されれば、いつでもFlightRecorderを起動することができます。
JFR.startでFlightRecorderが起動できるわけですが、
まずは、どのようなオプションがあるのかを確認します。


解析対象アプリケーションのプロセスIDを確認して、

$ jcmd
18519 org.apache.catalina.startup.Bootstrap start
18738 sun.tools.jcmd.JCmd

jcmdのhelpコマンドを利用して、JFR.startのヘルプを表示します。

$ jcmd 18519 help JFR.start18519:
JFR.start
Starts a new JFR recording

Impact: Low:

Syntax : JFR.start [options]

Options: (options must be specified using the or = syntax)
name : [optional] Name of recording (STRING, no default value)
defaultrecording : [optional] Starts default recording (BOOLEAN, false)
...


それでは実際に起動してみましょう。

$ jcmd 18519 JFR.start delay=1s duration=10s filename=./record.jfr
18519:
Started recording 1

このオプションでは、コマンド実行の1秒後から、10秒間の記録を行ない、
record.jfrという名前のファイルに記録を出力する、という動きになります。


コマンド実行から11秒ほどしてから、カレントディレクトリに
record.jfrが生成されれば成功です。


11秒間は別にじっと待っている必要はなく、
せっかくなので http://localhost:8080/ にアクセスして
サンプルアプリなどを動かしてみると良いでしょう。

5. FlightRecorderの結果をMissionControlで閲覧

では最後に、record.jfrをMissionControlで閲覧しましょう。


Mission Controlのメニューから、
[File] - [Open File]から、上で出力したrecord.jfrを開きます。
すると・・・

出た! ように、見える!


先に書いた通り、残念ながらいまのバージョンのFlightRecorderでは
詳細な情報を取得していないため、空っぽの結果が閲覧できるのみです。
Tomcat上でアプリケーションを動かそうが動かすまいが、得られる出力は同じなのです。


なお、拡張子をjfr以外にしていると、上手く読み込めないので注意してください。

まとめ

Java7 update4以降のHotspot JavaVMに、
JRockitのコマンドであるjcmdが導入され、FilghtRecorderも利用できるようになりました。
そのおかげで、これまで出来なかったMac単体でのFlightRecorder記録や
記録結果の閲覧も、ついに出来るようになりました。


ただ残念ながら、現バージョンでは情報が全く取得できていませんが、
4月頃に予定されている、Java7 update12から情報が取得できるようになるようです。
その頃には改めて、FlightRecorderの使い方や
具体的なトラブルシュート手順などを紹介したいですね。


それでは、お楽しみに!