6

最近、Java の効率性に関する議論に参加しました。私が聞いたところによると、Java に対する反対意見の多くは、解釈には「非常に時間がかかる」というものでした。そのため、単純な Java プログラムでさえ、機械語に直接コンパイルされた同様のプログラムよりもはるかに遅く実行されます。

それに対する答えは、Java コードは多くの場合、マシン コードに直接コンパイルされるというものでした。JVM のみが計算する場合、標準的な方法で解釈される場合よりもプログラムが高速になります。

私の質問は、JVM がジャストインタイム コンパイルを実行することを実際に「決定」するのはいつですか? JIT を標準のバイトコード解釈よりも効率的にする基準は何ですか? つまり、コンパイル自体に時間がかかりますが、私が理解している限り、プログラムが既に実行されているときにすべてが発生するはずです?

4

1 に答える 1

10

これは、JVM とその設定によって大きく異なります。ウィキペディア:

たとえば、Sun の Java 仮想マシンには、クライアントとサーバーという 2 つの主要なモードがあります。クライアント モードでは、最小限のコンパイルと最適化が実行され、起動時間が短縮されます。サーバー モードでは、広範なコンパイルと最適化が実行され、起動時間を犠牲にしてアプリケーションの実行中のパフォーマンスを最大化します。他の Java ジャストインタイム コンパイラは、メソッドが実行された回数のランタイム測定値とメソッドのバイトコード サイズを組み合わせて、いつコンパイルするかを決定するヒューリスティックとして使用しています。[4] さらに別の方法では、ループの検出と組み合わせて実行回数を使用します[5]。

-server モードの通常の HotSpot JVM の大まかな概算は、JVM が特定のメソッドが頻繁に (通常は特定の回数よりも多く) 呼び出されたことに気付いたときに JIT が発生することです。(これが、JVM が「HotSpot」と呼ばれる理由です。コード内の「ホット スポット」を識別して最適化するためです。) この時点で、JVM はいくつかのことを認識しています。

  • このメソッドは、最適化に時間を費やす価値があることを認識しています。なぜなら、このメソッドは頻繁に呼び出されるからです。
  • この関数の実際の特性について多くのことを知っています。
    • ステートメントの 1 つの分岐がif別の分岐よりもはるかに一般的である場合、 分岐予測を改善できます。
    • たとえば、Listこのメソッドに渡される a は通常 anArrayListであるため、 an の特定のケースに対して最適化とインライン化を行うことができますArrayList

マシンコードに事前にコンパイルした場合、最適化するためのこの情報が多くないことに注意してください。コンパイラは、どのパスが他のパスよりも一般的であるかを事前に知りません。しかし、実際のデータが得られるまで最適化を行うのを待つと、より適切な最適化の決定を下すことができます。

JIT の機能の詳細については、こちらを参照してください。

于 2013-08-13T23:24:05.383 に答える