web-dev-qa-db-ja.com

ジャストインタイム(JIT)コンパイラは何をするのですか?

JIT以外のコンパイラとは対照的に、JITコンパイラは特に何をしますか?誰かが簡潔でわかりやすい説明をすることができますか?

472
Michiel Borkent

JITコンパイラはプログラムの起動後に実行し、コード(通常はバイトコードまたは何らかの種類のVM命令)をオンザフライで(または通常はより高速な形式、通常はホストCPUのネイティブ命令セットに変換されます。 JITは動的なランタイム情報にアクセスできますが、標準のコンパイラは頻繁に使用される関数をインライン化するなどの最適化を行いません。

これは、allコードを機械語にコンパイルしてプログラムを最初に実行する従来のコンパイラとは対照的です。

言い換えれば、従来のコンパイラは、プログラムを初めて実行する前に、プログラム全体をEXEファイルとして作成します。新しいスタイルのプログラムでは、アセンブリは擬似コード(pコード)を使って生成されます。 (JIT)コンパイラは、OS上でプログラムを実行した(たとえば、そのアイコンをダブルクリックする)ことによって初めて、Intelベースのプロセッサなどが理解できるようなマシンコード(mコード)を生成します。

468
Mark Cidade

最初は、コンパイラが高水準言語(アセンブラよりも高いレベルとして定義されている)をオブジェクトコード(機械語命令)に変換し、それを(リンカによって)リンクして実行可能ファイルにすることを担当していました。

言語の進化のある時点では、コンパイラは高水準言語を疑似コードにコンパイルし、それが(インタプリタによって)解釈されてプログラムを実行します。これにより、オブジェクトコードと実行可能ファイルが削除され、これらの言語を複数のオペレーティングシステムとハードウェアプラットフォームに移植できるようになりました。 Pascal(これはP-Codeにコンパイルされた)は最初のもののうちの1つでした。 JavaとC#はもっと最近の例です。ほとんどの疑似演算は1バイトの長さであるため、最終的にPコードという用語はバイトコードに置き換えられました。

ジャストインタイム(JIT)コンパイラは、ランタイムインタープリタの機能です。メソッドが呼び出されるたびにバイトコードを解釈するのではなく、実行中のマシンのマシンコード命令にバイトコードをコンパイルしてから呼び出します。代わりにオブジェクトコード理想的には、オブジェクトコードを実行することの効率は、プログラムが実行されるたびにプログラムを再コンパイルすることの非効率性を克服するでしょう。

243
Craig Trader

JIT - 必要なときにWord自体がジャストインタイムで(オンデマンドで)言う

典型的なシナリオ

ソースコードは完全に機械語に変換されます

JITシナリオ

ソースコードは、構造体のようなアセンブリ言語に変換されます[C#の場合はIL(中間言語)、Javaの場合はByteCode]。

アプリケーションが必要とする場合にのみ中間コードが機械語に変換され、それが必要なコードが機械語に変換されるだけである。

JITと非JITの比較

  • JITでは、すべてのコードが最初にマシンコードに変換されるわけではないため、必要なコードの一部がマシンコードに変換され、呼び出されたメソッドや機能がマシンにない場合は、マシンコードに変換されますCPUの負担.

  • マシンコードは実行時に生成されるので.... JITコンパイラはマシンのCPUアーキテクチャを実行するために最適化されたマシンコードを生成します。

JITの例:

  1. JavaではJITはJVM(Java仮想マシン)にあります
  2. C#ではCLR(Common Language Runtime)にあります
  3. Androidでは、DVM(Dalvik Virtual Machine)、または新しいバージョンではART(Android RunTime)で提供されています。
63
Durai Amuthan.H

他が述べたように

JITはJust-in-Timeの略で、実行前ではなく、必要なときにコードがコンパイルされることを意味します

上記の議論にポイントを追加するために、JVMは関数が実行された回数としてカウントを維持します。この数が事前定義された制限を超えると、JITはコードをプロセッサで直接実行できる機械語にコンパイルします(javacがコードをバイトコードにコンパイルしてからJavaに変換する通常の場合とは異なり)マシンコードと実行)。

また、次回この関数が計算されるときには、コードが1行ずつ解釈される通常の解釈とは異なり、同じコンパイル済みコードが再度実行されます。これにより実行が速くなります。

25
Aniket Thakur

JITコンパイラは、最初の実行時にバイトコードを同等のネイティブコードにコンパイルするだけです。連続して実行するたびに、JVMはパフォーマンスを最適化するためにすでにコンパイル済みのネイティブコードを使用するだけです。

enter image description here

JITコンパイラがないと、JVMインタプリタはバイトコードを1行ずつ変換して、ネイティブアプリケーションが実行されているように見せます。

enter image description here

出典

11
user8885515

(アーキテクチャに依存しない)バイトコードがJavaコンパイラによって生成された後、実行はJVM(Java)によって処理されます。バイトコードはローダーによってJVMにロードされ、その後各バイト命令が解釈されます。

メソッドを複数回呼び出す必要があるときは、同じコードを何度も解釈する必要があり、これには必要以上に時間がかかることがあります。だから私たちはJIT(ジャストインタイム)コンパイラを持っています。バイトがJVMにロードされると(ランタイム)、コード全体が解釈されるのではなくコンパイルされるため、時間が節約されます。

JITコンパイラは実行時にのみ機能するため、バイナリ出力はありません。

9
User

JITはJust-in-Timeの略で、実行前ではなく必要なときにコードがコンパイルされることを意味します。

コンパイラは特定のマシンに最適化されたコードを生成できるため、これは有益です。あなたの普通のCコンパイラのような静的コンパイラは、開発者のマシン上の実行可能コードにすべてのコードをコンパイルします。したがって、コンパイラはいくつかの仮定に基づいて最適化を実行します。ユーザーにとってプログラムの実行が遅くなることはないため、コンパイルが遅くなり、最適化がさらに行われます。

9
Brian Lyttle

ジャストインタイムコンパイラ(JIT):
Javaバイトコードをその特定のCPUの機械語命令にコンパイルします。

たとえば、Javaコードにloop文があるとします。

while(i<10){
    // ...
    a=a+i;
    // ...
 }

Iの値が0の場合、上記のループコードは10回実行されます。

同じ命令が10回実行されるため、バイトコードを10回繰り返しコンパイルする必要はありません。その場合、そのコードを1回だけコンパイルする必要があり、値は必要な回数だけ変更できます。そのため、Just In Time(JIT)コンパイラは(前述のように)そのようなステートメントやメソッドを追跡し、パフォーマンスを向上させるためにそのようなバイトコードをマシンコードにコンパイルします。

別の同様の例は、文字列/文のリストの中で "Regular Expression"を使用してパターンを検索することです。

JITコンパイラは、すべてのコードをマシンコードにコンパイルするわけではありません。実行時に同様のパターンを持つコードをコンパイルします。

詳しくは、この JITの理解 に関するOracleのドキュメントを参照してください。

7
Anands23

私はこれが古いスレッドであることを知っています、しかしランタイム最適化はJITコンパイルのもう一つの重要な部分ですここで議論されていないようです。基本的に、JITコンパイラは実行時にプログラムを監視して実行を改善する方法を決定できます。その後、ランタイム中にそれらの変更を即座に行うことができます。 Google JIT最適化(javaworldにはそれについての かなり良い記事があります。

4
eze

IL(中間言語)にコンパイルされたコードがあります。プログラムを実行すると、コンピュータはこのコードを理解しません。ネイティブコードしか理解できません。そのためJITコンパイラは、ILをその場でネイティブコードにコンパイルします。メソッドレベルでこれを行います。

4
Charles Graham

ジャストインタイムコンパイラ(JIT)は、実行不可能な入力を受け取り、実行する適切なマシンコードを返すソフトウェアです。例えば:

Intermediate representation    JIT    Native machine code for the current CPU architecture

     Java bytecode            --->        machine code
     Javascript (run with V8) --->        machine code

その結果、特定のCPUアーキテクチャーには適切なJITコンパイラーをインストールする必要があります。

差分コンパイラ、インタプリタ、およびJIT

ソースコードをマシンコードに変換したいときは、一般的に例外があるかもしれませんが、使用することができます。

  1. コンパイラ:ソースコードを受け取り、実行ファイルを返します
  2. インタプリタ:命令ごとにプログラム命令を実行します。これはソースコードの実行可能セグメントを取り、そのセグメントを機械語命令に変換します。このプロセスは、すべてのソースコードが機械語命令に変換され実行されるまで繰り返されます。
  3. JIT:JITのさまざまな実装が可能ですが、JITは通常、コンパイラとインタプリタの組み合わせです。 JITはまずそれが受け取る中間データ(例えばJava(登録商標)バイトコード)を解釈によって機械語に変換する。 JITは、コードの特定の部分が頻繁に実行されることを感知することが多く、実行時間を短縮するためにこの部分をコンパイルします。
2

Jitは、ジャストインタイムコンパイラの略で、Javaバイトコードをプロセッサに直接送信できる命令に変換するプログラムです。

特定のシステムプラットフォームでJavaのジャストインタイムコンパイラ(実際には2番目のコンパイラ)を使用すると、バイトコードが特定のシステムコードにコンパイルされ、jitコンパイラによってコードが再コンパイルされると、通常コンピュータでより速く実行されます。

ジャストインタイムコンパイラは仮想マシンに付属しており、オプションで使用されます。バイトコードをプラットフォーム固有の実行可能コードにコンパイルし、それが直ちに実行されます。

2
user3459027

ジャストインタイム(JIT)コンパイル(動的翻訳またはランタイムコンパイル)は、コンピューターコードを実行する方法ですそのプログラムの実行中にコンパイルを伴う–実行時–実行前ではなく 。

ITコンパイルは、の2つの従来のアプローチによるマシンコードへの変換の組み合わせ–ahead-of-timeコンパイル( AOT)、およびinterpretation–および両方の長所と短所を組み合わせます。 JITコンパイルは、コンパイルされたコードの速度と解釈の柔軟性を組み合わせます

JVMで使用されるJITを考えてみましょう。

たとえば、HotSpot JVM JITコンパイラーは動的最適化を生成します。言い換えれば、彼らはJavaアプリケーションの実行中に最適化の決定を行い、基礎となるターゲット向けの高性能ネイティブマシン命令を生成しますシステムアーキテクチャー。

メソッドがコンパイル用に選択されると、JVMはそのバイトコードをJust-In-Timeコンパイラー(JIT)に送ります。 JITは、メソッドを正しくコンパイルする前に、バイトコードのセマンティクスと構文を理解する必要があります。 JITコンパイラーによるメソッドの分析を支援するために、そのバイトコードはまず、トレースツリーと呼ばれる内部表現で再構成されます。これは、バイトコードよりもマシンコードに似ています。その後、メソッドのツリーに対して分析と最適化が実行されます。最後に、ツリーはネイティブコードに変換されます。

トレースツリーは、プログラミングコードのランタイムコンパイルで使用されるデータ構造です。トレースツリーは、ホットスポット中に実行されるコードをトレースしてコンパイルする「ジャストインタイムコンパイラー」のタイプで使用されます。 this を参照してください。

参照:

1
prime

非JITコンパイラはソースコードを受け取り、コンパイル時にそれをマシン固有のバイトコードに変換します。 JITコンパイラは、コンパイル時に生成されたマシンに依存しないバイトコードを受け取り、実行時にそれをマシン固有のバイトコードに変換します。 Javaが使用するJITコンパイラは、単一のバイナリを変更なしで多数のプラットフォームで実行できるようにするものです。

1
David

次のコード例は、JITがJavaコードを最適化する方法を示しています。

最適化前のコード

    class A {
      B b;
      public void newMethod() {
        y = b.get();
        ...do stuff...
        z = b.get();
        sum = y + z;
      }
    }

class B {
   int value;
   final int get() {
      return value;
   }
}

最適化後のコード

class A {
B b;
public void newMethod() {
   y = b.value;
   ...do stuff...
   sum = y + y;
}
}
class B {
   int value;
   final int get() {
      return value;
   }
}

元々、コードにはb.get()メソッドへの2つの呼び出しが含まれていました。最適化後、2つのメソッド呼び出しは単一の変数コピー操作に最適化されます。つまり、最適化されたコードはクラスBのフィールド値を取得するためにメソッド呼び出しを実行する必要はありません。

JITコンパイラを使用して、JavaソースコードはJavaバイトコード(.classファイル)に変換されます。これが完了すると、JVMは実行時に.classファイルをロードし、インタプリタを使用してそれらをマシンが理解できるコードに変換します。

JITコンパイラはJVMの機能です。有効にすると、JVMはメソッド呼び出しをバイトコードで分析し、それらをよりネイティブで効率的なコードにコンパイルします。 JITはこの時点で優先順位の高いメソッド呼び出しを最適化します。

これらのメソッド呼び出しがコンパイルされると、JVMは解釈されるのではなくこの最適化されたコードを実行します。これにより、実行のパフォーマンスが向上する可能性があります。

プログラムが実行されるたびにソースコードをコンパイルしなければならない通常のコンパイラではなく

0
sabeen kanwal

パフォーマンス上の理由から、JVMは実行時に実際にコンパイル手順を実行します。つまり、Javaにはコンパイルと実行が明確に区別されていません。最初に、Javaソースコードからバイトコードへのいわゆる静的コンパイルを行います。その後、このバイトコードは実行のためにJVMに渡されます。しかし、バイトコードの実行は遅いので、JVMはバイトコードが実行される頻度を測定し、頻繁に実行されるコードの「ホットスポット」を検出すると、「ホットスポット」コードのバイトコードからマシンコードへの動的コンパイルを実行します。そのため、今日のJavaプログラムは、事実上、マシンコードの実行によって実行されています。

0
hi.nitish

バイトコードの20%が80%の時間使用されます。 JITコンパイラはこれらの統計情報を取得し、インラインメソッドの追加、未使用のロックの削除などを行い、そのマシン固有のバイトコードを作成することで、この20%のバイトコードを高速化します。私はこの記事から引用しています、私はそれが便利であると思いました。 http://Java.dzone.com/articles/just-time-compiler-jit-hotspot

0
Santosh budhe

JITは、いくつかのJVM実装で実行エンジンと呼ばれています。高速ではあるがより多くのメモリを必要とするものは、ジャストインタイムコンパイラです。この方式では、メソッドが最初に呼び出されたときに、メソッドのバイトコードがネイティブのマシンコードにコンパイルされます。メソッドのネイティブマシンコードはキャッシュされるので、次回同じメソッドが呼び出されたときに再利用できます。