JVM はどのようにプログラムを実行しているのか
Runtime Data Area に取り込まれたバイトコードは、Execution Engine と呼ばれるシステムで実行されているようです。
バイトコードを読み込み、少しずつ実行していきます。
Execution Engine も複数の仕組みで構成されています。
Execution Engine
1. Interpreter
この Interpreter はバイトコードの解釈は速いですが、実行速度は遅いです。
不利な点として、1つのメソッドが何度も呼ばれる場合、毎回新しく解釈が行われる点です。
2. JIT Compiler
JIT Compiler は Interpreter の不利な点を解消してくれます。
Execution Engine は Interpreter によってバイトコードを変換していきます。
ただし、もし繰り返しコードが見つかるとJITコンパイラが使用され、バイトコード全体をコンパイルしてネイティブコードに変換します。
このネイティブコードは、システムのパフォーマンスを向上させるため、繰り返しメソッド呼び出し時に直接使用されます。
更に、この JIT Compiler は複数の機能によって構成されているようです。
1. Intermediate Code generator
中間コードを生成します。
2. Code Optimizer
中間コードの最適化を行います。
3. Target Code Generator
機械語、もしくはネイティブコードを生成します。
4. Profiler
あるメソッドが複数回呼び出されているかどうかなど、ホットスポット’(JVMのHotSpotとは違う)を見つける。
所感
実行パートにおいて、Interpreter と Compiler が上手く共同作業しているのだと感じる。
final 修飾子が付いた変数やメソッドは、JIT Compiler に最適化のヒントを与えているという記事を見たことがあるが、本当だろうか。
ここで知る限りは、繰り返し呼ばれるかどうかがポイントであって、final であるかどうかはそれほど大きな影響はないのかもしれない。