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

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

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とは違う)を見つける。

3. Garbage Collector

参照されていないオブジェクトを集めて、取り除きます。
"System.gc()" でも呼び出されますが、特に保証されていない動作です。

その他の構成要素として、
Java Native Interface (JNI) は Native Method Libraries と相互作用し、Execution Engine が必要とする Native Libraries を提供する。
Native Method Libraries は、Execution Engine が必要としている Native Libraries の集まり。

所感

実行パートにおいて、Interpreter と Compiler が上手く共同作業しているのだと感じる。
final 修飾子が付いた変数やメソッドは、JIT Compiler に最適化のヒントを与えているという記事を見たことがあるが、本当だろうか。
ここで知る限りは、繰り返し呼ばれるかどうかがポイントであって、final であるかどうかはそれほど大きな影響はないのかもしれない。

f:id:blueskyarea:20180607010901p:plain