68
JVMコードリーディング入門 - JVMOS抽象化レイヤーについて - 虎塚 November 9, 2013 JJUG CCC 2013 Fall R5-5

JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

Embed Size (px)

DESCRIPTION

JJUG CCC 2013 Fallで発表しました。

Citation preview

Page 1: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

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

虎塚

November 9, 2013JJUG CCC 2013 Fall

R5-5

Page 2: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

自己紹介

鳥形由希 (id: torazuka)(株)電通国際情報サービス勤務

http://twitter.com/torazukahttp://d.hatena.ne.jp/torazuka/

Page 3: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

この入門セッションが生まれた経緯

Page 4: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

皆さんなら何のテーマで入門セッションをしますか?

Page 5: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

相談して題目をもらいました

JVMのソースコードについて話せばよいのでは?

ぎゃっぱぎゃっぱ

某上司

本当にありがとうございました.

メモリらへん

Page 6: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

このセッションのテーマ

● JVM(Java Virtual Machine)を読む基本的な方法

● JVMのOS抽象化レイヤーの構成

○ 基本的な方法を使ってソースコードを読むと,

どんなことが分かるかを共有します

Page 7: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

発表内容

1. JVMコードリーディング入門

1.1. ソースコードの入手からツールの選定まで

1.2. JVMソースコードの読み方

2. JVMのOS抽象化レイヤー

3. まとめ

Page 8: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

対象のソースコード

OpenJDK(http://openjdk.java.net/)

OpenJDK

Oracle JDK7

78

8

JDK7のベース,Java7のOSS版

JDK8のベースになる予定

7u

JDK7のupdate

6JDK7のベース,Java6のOSS版 今回は7u

Page 9: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ソースコードの入手

● zipで取得する

○ メリット:入手が簡単、解凍すれば読める

○ デメリット:提供バージョンが固定の場合がある

● ソースコードリポジトリから取得する

○ メリット:好きなバージョンを入手できる

○ デメリット:読むまでに苦労する場合もある,

java.netが繋がりづらい

Page 10: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

リポジトリからソースコードを入手する

sudo apt-get install mercurial

1. Mercurialをインストールする

2. hgforest-crewからforest.pyをダウンロードして任意の場所に置く

3. 設定ファイルhgrcにforest.pyを使う設定を追記

4. リポジトリからコードをcloneする

[extensions]forest={forest.pyを置いたディレクトリパス}/forest.py

hg clone http://hg.openjdk.java.net/jdk7u/jdk7u hgforest

(追記)下記手順の代わりにget_source.shを実行する方法もあります

Page 11: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ビルド

● デバッグ実行しながら動作を調べるなら必要○ ビルドツールの理解

○ 依存ライブラリの取得

○ 環境変数の設定

● 動かす前の調査としてコードを読むなら不要○ ビルドで生成されるソースコードがある場合は注意

OpenJDKのビルド方法は,README_builds.html参照

Page 12: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

(参考)ビルドしようよ派

 (略)次の理由でビルドすることを勧めます.

 第一の理由は,ビルド処理の工程でソースファイル自体を生成することが

あるからです.(略)第二の理由は、Apacheのような巨大なソフトウェア特有

の事情です.(略)該当するソースコードがコンパイルされていない,つまり実

行ファイルに含まれてもいない,ことがあります.(略)最後の理由は,やや

気分的なものですが,そもそもビルドすら通せないソースでは,読むことは難

しいはずです.

(引用)WEB+DB PRESS Vol.69,p.133(松原克弥さん,井上誠一郎さん)

Page 13: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

(参考)ビルドは最終手段派

gdb動作を調べる必要があるときに使います。

ただし、これは最終手段です。読んですぐに理解できるものなら実際に動か

して調べる必要はまったくありません。どうしてもわからないときに使いましょ

う。

よくわからないプロジェクトのビルドは面倒ですし、対象の関数を動かすのは

もっと面倒ですから。

(引用)ソースコードを読むときの3カ条(nariさん) http://d.hatena.ne.jp/authorNari/20111213/1323745618

Page 14: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ツール(1) エディタ

● C, C++ソースコードを扱い慣れているエディタ

○ Emacs, vi, 秀丸...お好きなエディタでどうぞ

● エディタが持っていて欲しい機能○ 正規表現が使える検索

○ ブックマーク

○ シンタックスハイライティング

Page 15: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ツール(2) エディタ続き

● サクラエディタ○ http://sakura-editor.sourceforge.net/○ for Windows(8にも対応)○ もし習熟したエディタがまだないならいいかも

● Eclipse IDE for C/C++ Developers○ http://www.eclipse.org/downloads/○ ただし,C, C++のコードを真っ当に読めるように

設定するのは大変…

Page 16: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ツール(3) エディタ以外

● 正規表現

○ ファイル内検索,キーワード抽出

● grep○ 正規表現と組み合わせて使うと便利

● ctags○ クラスや関数の定義にジャンプ

○ 同名のヘッダファイル/ソースコードにジャンプ

Page 17: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

発表内容

1. JVMコードリーディング入門

1.1. ソースコードの入手からツールの選定まで

1.2. JVMソースコードの読み方

2. JVMのOS抽象化レイヤー

3. まとめ

Page 18: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ソースコードの読み方

1. 全体の階層構造を把握する

2. ファイルの関係を把握する

3. クラスの関係を把握する

何周も繰り返す

Page 19: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ポイント

● 分からなくても全部をざっくり何周も読む○ 実装の詳細や構文,テクニックに固執して止まらない

● メモをとったり図解したりする● 仮説と検証を繰り返す

○ 予想と実際の差分を見る○ 仮説で理解を橋渡しする

● 粒度を行き来して徐々に焦点を合わせる

Page 20: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ディレクトリ構造を見る(10%程度?)

Page 21: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ディレクトリ構造を読む(50%程度?)

Page 22: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ディレクトリ構造を理解する(100%)

Page 23: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

コントラクトを見る(10%程度)

Page 24: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

コントラクトを読む(50%程度?)

Page 25: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

コントラクトを理解する(100%)

Page 26: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ロジックを見る(10%程度?)

Page 27: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ロジックを読む(50%程度?)

Page 28: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ロジックを理解する(100%)

Page 29: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

1. 全体の階層構造を把握する

● ディレクトリ構成を見る● どんな名前空間があるか見る

● ファイルサイズの大きいものを把握する

● 抽象度の高い名前のファイルを把握する

Page 30: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

2. ファイルの関係を把握する

● 中心的なファイルと周縁のファイルを推定する

○ 直接のinclude関係に着目して,図にしてみる

Page 31: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

3.1. クラスの関係を把握する

● 他のクラスと関係性をたくさん持つクラスを把握する

● クラスと構造体をすべて抽出し,継承関係を図にする

Page 32: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

3.2. C,C++レイヤーの切り分け

● クラスがどのレイヤーに属するかを見る

○ システムコールを行う層と、それを使う層

○ Cの構造体がC++のレイヤーに漏れないように

なっているはずなので、それを確かめる

● OSと接する末端を見つけ,

JVMとOSの境界を把握するOS

C

C++

Page 33: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

「ざっくり読む」とは

● たとえばヘッダファイルだけをまず読む

● 役割と責任範囲に着目する

○ ヘッダコメントを読む

○ シグネチャに着目して読む

○ ファイルにどんなクラスがあるかを見る

○ クラスにどんなフィールドや関数があるかを見る

Page 34: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

photo by http://www.ashinari.com

漆塗りのように理解することを目指します

Page 35: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

読む部分と読み飛ばしてもよい部分

● assert文 →読む

○ コントラクトなので非常に重要

● non-PRODUCTコード →読み飛ばしてもOK○ NOT_PRODUCT(code)のようなマクロ部分

Page 36: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ソースコードのコメントをどう読むか

● 実行できないので全幅の信頼は置けないが・・・

● ヘッダファイルのコメントは基本的に読む

○ 設計指針や専門用語の解説

● ソースファイルのコメントは次の場合に読む

○ 署名がついているもの

○ バグトラッカーの番号がついているもの

○ 新しい日付が書いてあるもの(OpenJDK正式リリース以降)※2011年7月28日

Page 37: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

JVMの抽象クラスの特性

● 派生クラスがオーバーライドすべき関数を持つ

○ 純粋仮想関数

○ 直接インスタンス化できないように,new,

deleteの関数にエラー処理が書いてあることも

Page 38: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

抽象クラス(余談)

gccなど特定のコンパイラでは,基底クラスを持つクラスは

(仮想関数やフィールドがなくても)バイナリが大きくなる.

そのため,クラス定義に基底クラスを直接書かずマクロにする.

そのようなコンパイラでコンパイルした時は,マクロが空文字列

に変換される.

c.f. hotspot/src/share/vm/memory/allocation.hpp

Page 39: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

メモリ周りのコードによく出てくる略語

略語 フルスペル

oop ordinary object pointer

RO ResourceObj

TLAB thread local allocation buffers

BOT blockOffsetTable

Page 40: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

発表内容

1. JVMコードリーディング入門

1.1. ソースコードの入手からツールの選定まで

1.2. JVMのソースコードをどう読むか

2. JVMのOS抽象化レイヤー

3. まとめ

Page 41: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

読みたいところ

● OSからJVMがメモリを確保する部分

● OSから取得したメモリを管理する部分

Page 42: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

OpenJDK7のディレクトリ構造 (抜粋)

dir名 中身 実装言語

corba CORBA API, rmic Java

hotspot コンパイラ,GC C++

jaxp JAXP API Java

jaxws JAXB, JAX-WS API Java

jdk コアライブラリ Java, C

langtools Compiler API Java

Page 43: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

HotSpotのディレクトリ構造 (抜粋)

src/

os/

os_cpu/

cpu/

share/

linux/

solaris/

windows/

vm/

vm/

vm/

posix/ vm/

vm/

tools/ runtime/

memory/

他多数のディレクトリ

←OSごとの実装

Page 44: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

JVM

今回まず読む部分 OS抽象化層

OS

OS抽象化層

メモリ管理

GC

アプリケーション

オブジェクト管理

ここ

Page 45: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

os.cpp

OS抽象化層

Linux Windows Solaris

os_linux.hpp

os_windows.hpp

os_solaris.hpp

メモリ管理の機能

Page 46: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

OS別のinclude#ifdef TARGET_OS_FAMILY_linux# include "os_linux.inline.hpp"# include "thread_linux.inline.hpp"#endif#ifdef TARGET_OS_FAMILY_solaris# include "os_solaris.inline.hpp"# include "thread_solaris.inline.hpp"#endif#ifdef TARGET_OS_FAMILY_windows# include "os_windows.inline.hpp"# include "thread_windows.inline.hpp"#endif

hotspot/src/share/vm/runtime/os.cpp#L51-62

Page 47: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

OS別のinclude hotspot/src/share/vm/runtime/os.hpp#L33-41

#ifdef TARGET_OS_FAMILY_linux# include "jvm_linux.h"#endif#ifdef TARGET_OS_FAMILY_solaris# include "jvm_solaris.h"#endif#ifdef TARGET_OS_FAMILY_windows# include "jvm_windows.h"#endif

hotspot/src/os/{os_name}/vm/jvm_{os_name}.hをincludeする

Page 48: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

os.hppに定義されたメンバー

● static関数が250個ほどある○ os_linux.hppは140個ほどオーバーライド○ os_windows.cppは150個ほどオーバーライド

● メモリ管理に関するもの,別の役割のもの

Page 49: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

os::関数を呼び出すクラスの場所

asmc1classfilecodecompilergc_implementationinterpreterlibadt

memoryoopsoptoprimsruntimeservicessharkutilities

hotspot/src/share/vm/以下のディレクトリ

Page 50: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

memory/以下で使われるos::関数

mallocfreenum_mallocsalloc_bytesfree_bytesreallocvm_allocation_granularity・・・・80箇所くらいで30種類くらい使われている

Page 51: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

osクラスの一部

public:

static void init(void); // Called before command line parsing static jint init_2(void); // Called after command line parsing static void init_3(void); // Called at the end of vm init

hotspot/src/share/vm/runtime/os.hpp#L98-102

痺れる

Page 52: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

次に読む部分 OS抽象化層の利用側

JVM

OS

OS抽象化層

メモリ管理

GC

アプリケーション

オブジェクト管理

ここ

Page 53: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

memory/の中身

● 80ファイルくらい(hpp, cpp)● 抽象度の高いファイル名を持つもの

○ allocation○ heap○ space○ generation○ universe・・・

Page 54: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

memory/のクラス継承関係

→画像

Page 55: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

memory/のクラス継承関係

StackObjCHeapObjValueObjAllStatic

なんか大事なクラスっぽい

Page 56: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

memory/のファイル

■赤=allocation.hpp■橙=赤ファイルを直接    includeするhpp■黄=橙ファイルを直接    includeするhpp

→画像

Page 57: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

memory/のファイル(抜粋)

heap

generation

resourceArea

memRegionallocation

compactPermGen

permGen genOopClosures

cardTableRS

genCollectedHeap

barrierSetblockOffset

Table

generationSpec iterator

watermark

spacetenuredGeneration

sharedHeap

Page 58: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

■赤=allocation.hppに    定義されたクラス

■橙=前頁の橙ファイルに    定義されたクラス

■黄=前頁の黄ファイルに    定義されたクラス

memory/のクラス継承関係(再)

→画像

Page 59: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

allocation.hpp|cppの重要なクラス

クラス名 説明

CHeapObj Cヒープに配置されるオブジェクト用

StackObj スタックに配置されるオブジェクト用

ValueObj 組み込みオブジェクト用

ResourceObj リソースエリアに配置されるオブジェクト用

AllStatic 名前空間として使われるクラス用

Page 60: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

CHeapObjの継承ツリー

space

resourceArea

generation

→画像

Page 61: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

StackObjの継承ツリー

iterator

space

genOopClosures

→画像

Page 62: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ValueObjの継承ツリー

Page 63: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

ResourceObjの継承ツリー

Page 64: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

AllStaticの継承ツリー

Page 65: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

photo by http://www.ashinari.com

以上のように腑分けしながら理解します

Page 66: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

発表内容

1. JVMコードリーディング入門

1.1. ソースコードの入手からツールの選定まで

1.2. JVMソースコードの読み方

2. JVMのOS抽象化レイヤー

3. まとめ

Page 67: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

まとめ

こうやって読んでいけばいずれ分かる!!!● 分からなくても全部をざっくり何周も読む● メモをとったり図解したりする● 仮説と検証を繰り返す● 粒度を行き来して焦点を合わせる

ご清聴ありがとうございました.

Page 68: JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」

参考資料

1. トップスタジオ,まつもとゆきひろ,平林俊一,鵜飼文敏:『Code Reading』,毎日コミュニケーションズ,2004.6.

2. 佐藤太一:「太一のコードの読み方メモ」,https://gist.github.com/taichi/2693387,2012.5.

3. 松原克弥,井上誠一郎:「C言語コードリーディング」,p.p.130-139,WEB+DB PRESS Vol.69,技術評論社,2012.6.

4. 中村成洋,相川光:『ガベージコレクションのアルゴリズムと実装』,秀和システム,2010.3.

5. 中村成洋:『徹底解剖「G1GC」実装編』,http://www.narihiro.info/g1gc-impl-book/,2013.5.

6. Alexey Ragozin:「Understanding GC pauses in JVM, HotSpot's minor GC.」,Grid Designer's Blog,2011.6.