Java仮想マシン-JIT最適化

この章では、JIT最適化について学習します。

メソッドのインライン化

この最適化手法では、コンパイラーは関数呼び出しを関数本体に置き換えることを決定します。以下は同じ例です-

int sum3;

static int add(int a, int b) {
   return a + b;
}

public static void main(String…args) {
   sum3 = add(5,7) + add(4,2);
}

//after method inlining
public static void main(String…args) {
   sum3 = 5+ 7 + 4 + 2;
}

この手法を使用すると、コンパイラーは、関数呼び出しを行うオーバーヘッドからマシンを節約します(パラメーターをスタックにプッシュおよびポップする必要があります)。したがって、生成されたコードはより高速に実行されます。

メソッドのインライン化は、非仮想関数(オーバーライドされない関数)に対してのみ実行できます。'add'メソッドがサブクラスでオーバーライドされ、メソッドを含むオブジェクトのタイプが実行時までわからない場合にどうなるかを考えてみてください。この場合、コンパイラはインライン化するメソッドを認識しません。ただし、メソッドが「final」としてマークされている場合、コンパイラーは、サブクラスによってオーバーライドできないため、インラインにできることを簡単に認識できます。最終的なメソッドが常にインライン化されるという保証はまったくないことに注意してください。

到達不能でデッドコードの除去

到達不能コードとは、実行フローによって到達できないコードです。次の例を考えてみましょう-

void foo() {
   if (a) return;
   else return;
   foobar(a,b); //unreachable code, compile time error
}

デッドコードも到達不能コードですが、この場合、コンパイラはエラーを吐き出します。代わりに、警告が表示されます。コンストラクター、関数、try、catch、if、whileなどのコードの各ブロックには、JLS(Java言語仕様)で定義された到達不能コードに対する独自のルールがあります。

定数畳み込み

定数畳み込みの概念を理解するには、以下の例を参照してください。

final int num = 5;
int b = num * 6; //compile-time constant, num never changes
//compiler would assign b a value of 30.