2

Java JIT コンパイルの使用について疑問に思っていました。私の理解では、「デッドコード」をコンパイルしようとする必要があります。私が疑問に思っているのは、何がデッド コードに分類されるかということです。

たとえば、debug というランタイム プロパティを false に設定したとします。私のプログラムにそのプロパティを取得し、それに基づいてメソッドを実行するコードがある場合、何がデッド コードとして分類されるのか疑問に思います。

public static final boolean DEBUG

static {
    DEBUG = System.getProperties().containsKey("debug.enabled");
}

public static void logDebug(String msg) {
    if (DEBUG) {
        System.out.println("My Debug Message");
    }
}

public static void main(String args) {
    // 1) Check if DEBUG is true and log if 
    // it is.
    //
    if (DEBUG) {
        System.out.println("My Debug Message");
    }

    // 2) Call a method to perform logging, let it check
    // DEBUG
    //
    logDebug("My Second Debug Message");

}

main では、最初の if ブロックが DEBUG をチェックします。それは間違いなので、JIT はこのブロックが決して実行されないことを認識し、デッド コードとしてコンパイルするだろうと思います。

同じことがlogDebugメソッドにも起こるかどうか疑問に思っていました-JVMは引き続きそのメソッドに毎回入りますか、それともそのメソッドで何も起こらないことを理解して最適化しますか?

おそらく、JIT がどのように機能するかについての私の理解は完全に間違っているのでしょうか?

4

1 に答える 1

2

JITは、デッドコードを常に完全に排除するとは限りません。

代わりに、ありそうもないケースを最適化するので、コストはほぼゼロになります。これは、CPUが分岐を超えてコードの投機的実行を実行でき、この分岐が実行されない場合、想定上のコストしか発生しないためです。これは、ブランチが一部の時間しか取得されない場合でも実行されます(つまり、取得される可能性が高いブランチとして1つのブランチを選択する必要があります)。

何らかの理由でこれが変更された場合でも、比較的遅い場合でも、コードは正しく動作します。JITは、それが行った最適化の仮定が変更されたことを検出し、コードを再最適化することができます。で、-XX:+PrintCompilation以前にコンパイルしたメソッドをダンプして再コンパイルしていることがわかります。

要するに、デッドコードはほとんどコストがかからないようになります。

于 2012-06-13T08:20:24.827 に答える