社内se × プログラマ × ビッグデータ

プログラミングなどITに興味があります。

JVM は どうやって class ファイルをロードしているのか

JVM クラッシュの調査をしていると、そもそも JVM の動作についてあまり知らなかったことに気づく。
大まかには、コンパイルによって生成された class ファイルを JVM が取り込んで、解析して、実行する。

その class ファイルを取り込むところを Class Loader Subsystem と呼ばれるものが担当しているらしい。
これは、プログラムの実行時に行われる処理であって、コンパイル時の処理ではない。

ロードの処理は更に、LoadingLinkingInitialization というステップに分けられる。

Class Loader Subsystem

1. Loading

まずは、class ファイルがロードされるが、以下の3種類のローダーが存在する。
Boot Strap ClassLoader は、rt.jar など、JREにとって最もコアとなるライブラリがロードされる。
Extension ClassLoader は、ext フォルダ内にある準コアとなるライブラリがロードされる。
Application ClassLoader は、CLASSPATH 内にあるライブラリがロードされる。

もし、ロード対象のクラスが見つからなかった場合、ClassNotFoundExceptionがスローされる。

2. Linking

class ファイルのロード後、バリデーション的なことが行われる。
Verifyでは、生成されたバイトコードが正しいものであるかどうかをチェックする。
Prepareでは、全ての static 変数がメモリ上にデフォルト値でロードされる。
Resolveでは、全ての シンボリックリンクが実際の参照先に置き換えられる。

もし、参照先のクラスが見つからなかった場合、ClassDefNotFoundExceptionがスローされる。

3. Initialize

全ての static 変数に設定値が与えられる。そして、static ブロック内の処理が実行される。

所感

class ファイルのロードだけでも、想像していたより細かいステップによって行われている印象を持った。
ClassNotFoundException と ClassDefNotFoundException はしばしば出くわしますが、それぞれがスローされるタイミングが分かったのが嬉しい。
f:id:blueskyarea:20180605001252p:plain