JJUG CCC 2013 Fall「JVMコードリーディング入門」資料公開

土曜にJJUG CCC 2013 Fall(http://www.java-users.jp/?page_id=695)へ行ってきました。

事前にお知らせするのを忘れていましたが、17:15〜18:05のセッションでJVMソースコードリーディングについてお話ししましたので、発表資料を公開します。

R5-5 JVMコードリーディング入門 〜JVMのOS抽象化レイヤーについて〜

JVMのコードを読みはじめたばかりの方を対象に、JVMとOSのメモリを中心とした関係性についてお話しします。JVMはOSからどのようにメモリを確保しているのでしょうか? そんな素朴な疑問をもとに、JVMのコードを楽しく追いかけてみましょう。※このセッションは入門者向けです。バイトコードGCについては扱いません。

虎塚
(さくらば組)

http://www.java-users.jp/?page_id=709#r5-5

スライド後半に出てくる図解から重要なクラスを絞り込む手順は、スライドだけを見ると分かりづらいと思いますので、下記で簡単に説明します。

フォローアップ

スライドの載せた画像は小さいので、当日ビューアで表示したオリジナル画像を貼っておきます。また、画像生成にはblockdiag(http://blockdiag.com/ja/)の1.3.1を使いましたので、そのテキストファイルも公開します。

1. クラス継承ツリーの作成

まず、正規表現grepを使ってmemoryディレクトリのhppファイルからすべてのクラス定義を抽出し、クラス継承関係のツリーを書きます。

この図から、より多くの派生クラスを持つクラスを把握します。

CHeapObj、StackObj、_ValueObj、AllStaticあたりが目立っています。

2. ファイルincludeツリーの作成

次に、memoryディレクトリにあるファイルのinclude関係を図解します。今回は、直接includeしているファイルにだけ注目しました。

右上の赤色のファイルは、1.で見つけたCHeapObj、StackObj、_ValueObj、AllStaticを含むallocation.hppです。これを重要なファイルだと推定します。

橙色のファイルは、allocation.hppを直接includeしているファイル群です。黄色のファイルは、橙色のファイルを直接includeしているファイル群です。

これによって、allocation.hppを中心としたinclude関係の広がりを把握します。

3. 重要そうなクラスの特定

そして、1.で作成したクラス継承ツリーに再度戻ります。

2.で推定した重要なファイル(allocation.hpp)に定義されているクラスを赤色にしました。CHeapObj、StackObj、ResourceObj、_ValueObj、AllStaticです。

そして、2.の橙色のファイルで定義されるクラスを橙色、黄色のファイルで定義されるクラスを黄色にしました。

このようにして読みたいソースコードの構造を把握し、重要そうなクラスを絞り込んでから読んでいく、という話でした。

(補足)allocation.hppで定義されたクラスの継承ツリーのオリジナル画像

会場での質疑応答

ご質問ありがとうございました。

non-PRODUCTコードにはどういった処理が書いてあるの?
主にJVMデバッグ用の処理です。デバッグ時に必要な情報を保持するためのクラスが、クラス定義丸ごとifndef PRODUCTブロック内に定義されていたりします。
これから大きいコードベースを読んでみようとする場合は、JVM以外の大きなプロダクトを読んだ方がいい? ちなみに、JVMについて特にここを知りたいという目的は持ってないです。
はい、その方がよいと思います。JVMのようにマルチプラットフォームに対応しようとするソースコードは、そのための処理だけでも膨大です。プラットフォーム対応の処理をより分けながら本質的な処理を読まなければなりません。OSをラップするせいで階層も厚くなり、コールシーケンスが長いので、デバッグ実行して動作を追うのも大変です。大規模なコードを読むこと自体が目的であれば、JVMにこだわらず、Webアプリケーションフレームワークやよく使うライブラリなどを読む方が楽しいと思います。
コールシーケンスを見たい時は、静的なリーディングで確認する? それとも動かして確認する?
動かして確認します。オーバーライドされた関数を静的な読み方で追うのは辛いですし、限定的なコールシーケンスしか把握できないためです。
ソースコードを読んでいてアルゴリズムの処理が理解できないときはどうする? たとえば、最近のソートのアルゴリズムは昔と違って意味不明だよねー。
動かして確認します。丸ごとビルドするのが大変な場合は、分からない箇所だけ手元にコピーして、関係ない行は消します。デバッガを使ったりprintデバッグしたりして動きを見ます。

発表内容の補足・訂正事項

  • JVMソースコードリポジトリから取得する場合のデメリットとして、「java.netが繋がりづらい」ことを挙げたところ、「java.netは常にDoS攻撃を受けているせい」という情報をいただきました。
    • Oracleさま〜〜がんばってくだされ〜〜
  • ソースコードのコメントを重視するケースの一つとして、OpenJDKとして正式リリースした後の日付が付いていること、という条件を挙げました。ここでスライドに「OpenJDK6」(の正式リリース日以降)と書きましたが、OpenJDK7の方がリリース日は古いという指摘をいただきました。
    • この話ですね。たしかにそうでした、すみません。http://openjdk.java.net/projects/jdk6/
    • 最初からバージョン番号でなく日付を書けばよかったですね。スライドに補足しました。OpenJDK7のGAは2011年7月28日です。

両方さくらばさんからのご指摘です。ありがとうございました。

感想

会場で挙手アンケートにご協力いただいたところ、参加された方の割合はこんな感じでした。

  • 仕事や趣味でJVMソースコードを頻繁に読んでいる人:5人未満
  • 稀に読むことがある人、以前少し読んだことがある人:10人前後
  • 読んだことがない人、いつか読もうと思ってダウンロードしたことがある人:残りの方

母数は50〜60人だったと思います。概ねターゲットとして想定していた方に来ていただけたようで良かったです。

予想外の満員で緊張しました(イスが足りず立ち見で参加してくださった方、すみませんでした)が、頷いたり笑ったりしながら聞いてくださる方が多く、質問やツッコミもいろいろと頂けたおかげで非常に話しやすくw 話そうと思っていたことは大体話せたと思います。

スライドの図や文字の大きさ、発表中のスクリーン上の位置の示し方など、伝え方の改善点も見つかり、勉強になりました。

セッションに参加してくださった方、JJUGの運営の皆さん、発表のきっかけをくださった櫻庭さん、なぎせさん、面白テーマをくれた太一さん、ありがとうございました。