非JITコンパイラーとは対照的に、JITコンパイラーは具体的に何をしますか?誰かが簡潔で理解しやすい説明を与えることができますか?
非JITコンパイラーとは対照的に、JITコンパイラーは具体的に何をしますか?誰かが簡潔で理解しやすい説明を与えることができますか?
回答:
JITコンパイラーは、プログラムの開始後に実行され、コード(通常はバイトコードまたはある種のVM命令)をその場で(または呼び出されるとジャストインタイムで)通常より高速な形式(通常はホストCPUのネイティブ)にコンパイルします。指図書。JITは動的ランタイム情報にアクセスできますが、標準コンパイラーはそうではなく、頻繁に使用される関数のインライン化などの最適化を行うことができます。
これは、プログラムが最初に実行される前にすべてのコードを機械語にコンパイルする従来のコンパイラーとは対照的です。
言い換えれば、従来のコンパイラーは、初めて実行する前に、プログラム全体をEXEファイルとしてビルドします。新しいスタイルのプログラムの場合、アセンブリは疑似コード(pコード)で生成されます。OSでプログラムを実行した後(アイコンをダブルクリックするなど)にのみ、(JIT)コンパイラが起動し、Intelベースのプロセッサなどが理解できるマシンコード(Mコード)を生成します。
当初、コンパイラーは高水準言語(アセンブラーよりも高いレベルとして定義)をオブジェクトコード(マシンインストラクション)に変換し、それを(リンカーによって)実行可能ファイルにリンクしていました。
言語の進化のある時点で、コンパイラーは高水準言語を疑似コードにコンパイルし、それを(インタープリターによって)解釈してプログラムを実行します。これにより、オブジェクトコードと実行可能ファイルが削除され、これらの言語を複数のオペレーティングシステムとハードウェアプラットフォームに移植できるようになりました。Pascal(P-Codeにコンパイルされた)は最初の1つでした。JavaとC#は最近の例です。結局のところ、疑似操作のほとんどがバイト長であるため、Pコードという用語はバイトコードに置き換えられました。
Just-In-Time(JIT)コンパイラーは、ランタイムインタープリターの機能であり、メソッドが呼び出されるたびにバイトコードを解釈する代わりに、バイトコードを実行中のマシンのマシンコード命令にコンパイルし、これを呼び出します。代わりにオブジェクトコード。理想的には、オブジェクトコードの実行効率により、プログラムを実行するたびにプログラムを再コンパイルする非効率性が克服されます。
JIT-必要なときに(必要に応じて)単語自体が言う
ソースコードは完全にマシンコードに変換されます
ソースコードは、構造のようなアセンブリ言語に変換されます[C#の場合はex IL(中間言語)、javaの場合はByteCode]。
中間コードは、アプリケーションで必要なコードのみがマシンコードに変換される必要がある場合にのみ、マシン言語に変換されます。
JITでは、すべてのコードが最初にマシンコードに変換されるわけではなく、必要なコードの一部がマシンコードに変換されます。次に、呼び出されたメソッドまたは機能がマシンにない場合、マシンコードに変換されます... CPUの負担。
マシンコードは実行時に生成されるため、JITコンパイラーは、マシンのCPUアーキテクチャーを実行するために最適化されたマシンコードを生成します。
他の人が述べたように
JITはJust-in-Timeの略です。つまり、実行前ではなく、必要なときにコードがコンパイルされます。
上記の説明にポイントを追加するだけで、JVMは関数が実行された回数のカウントを維持します。このカウントが事前定義された制限を超えると、JITはコードをマシン言語にコンパイルし、プロセッサーが直接実行できるようにします(javacがコードをバイトコードにコンパイルしてからJavaに変換する通常の場合とは異なり-インタープリターはこのバイトコードを1行ずつ解釈して、マシンコードと実行)。
また、次回この関数が計算されるときには、コードが行ごとに再度解釈される通常の解釈とは異なり、同じコンパイル済みコードが再度実行されます。これにより、実行が速くなります。
JITコンパイラは、最初の実行時にバイトコードを同等のネイティブコードにコンパイルするだけです。連続して実行されるたびに、JVMはすでにコンパイルされたネイティブコードを使用してパフォーマンスを最適化するだけです。
JITコンパイラーがない場合、JVMインタープリターはバイトコードを1行ずつ変換して、ネイティブアプリケーションが実行されているかのように見せます。
JITはJust-in-Timeの略です。つまり、実行前ではなく、必要なときにコードがコンパイルされます。
コンパイラーは特定のマシン用に最適化されたコードを生成できるため、これは有益です。平均的なCコンパイラのような静的コンパイラは、開発者のマシンで実行可能なコードにすべてのコードをコンパイルします。したがって、コンパイラーはいくつかの仮定に基づいて最適化を実行します。ユーザーのプログラムの実行速度を低下させないため、コンパイルが遅くなり、最適化が多くなります。
バイトコード(アーキテクチャーに中立)がJavaコンパイラーによって生成された後、実行はJVM(Java)によって処理されます。ローダーによってバイトコードがJVMにロードされ、各バイト命令が解釈されます。
メソッドを複数回呼び出す必要がある場合は、同じコードを何度も解釈する必要があるため、必要以上に時間がかかる場合があります。したがって、JIT(ジャストインタイム)コンパイラがあります。バイトがJVMにロードされると(そのランタイム)、コード全体が解釈されるのではなくコンパイルされるため、時間を節約できます。
JITコンパイラーは実行時にのみ機能するため、バイナリー出力はありません。
Just In Time Compiler(JIT):
Javaバイトコードをその特定のCPUのマシン命令にコンパイルします。
たとえば、Javaコードにループステートメントがある場合:
while(i<10){
// ...
a=a+i;
// ...
}
上記のループコードは、iの値が0の場合、10回実行されます。
同じ命令が10回実行されるため、バイトコードを10回コンパイルする必要はありません。その場合、そのコードを1回だけコンパイルする必要があり、必要な回数だけ値を変更できます。したがって、Just In Time(JIT)コンパイラーは、前述のようにそのようなステートメントとメソッドを追跡し、そのようなバイトコードをマシンコードにコンパイルしてパフォーマンスを向上させます。
同様の別の例は、文字列/文のリストで「正規表現」を使用してパターンを検索することです。
JITコンパイラは、すべてのコードをマシンコードにコンパイルするわけではありません。実行時に同様のパターンを持つコードをコンパイルします。
詳しくは、JITについてのOracleのドキュメントをご覧ください。
一部のIL(中間言語)に準拠したコードがあります。プログラムを実行すると、コンピューターはこのコードを理解しません。ネイティブコードのみを理解します。そのため、JITコンパイラは、ILをその場でネイティブコードにコンパイルします。これはメソッドレベルで行われます。
私はこれが古いスレッドであることを知っていますが、ランタイムの最適化はJITコンパイルのもう1つの重要な部分であり、ここでは説明されていないようです。基本的に、JITコンパイラは実行時にプログラムを監視して、実行を改善する方法を決定できます。次に、実行時にそれらの変更をその場で行うことができます。Google JIT最適化(javaworldにはかなり良い記事があります。)
ジャストインタイムコンパイラ(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は、ジャストインタイムコンパイラの略です。jitは、Javaバイトコードを、プロセッサに直接送信できる命令に変換するプログラムです。
特定のシステムプラットフォームでJavaジャストインタイムコンパイラー(実際には2番目のコンパイラー)を使用すると、バイトコードが特定のシステムコードにコンパイルされます。コードがjitコンパイラーによって再コンパイルされると、通常、コンピューターでより速く実行されます。
ジャストインタイムコンパイラは仮想マシンに付属しており、オプションで使用されます。バイトコードをプラットフォーム固有の実行可能コードにコンパイルして、すぐに実行します。
ジャストインタイム(JIT)コンパイル(動的変換またはランタイムコンパイルも)は、実行前ではなく、プログラムの実行中に(実行時に)コンパイルを含むコンピューターコードを実行する方法です。
ITは、コンパイルがあるの組み合わせ - 2つの伝統的なマシンコードに変換するためのアプローチ事前コンパイラ(AOT) 、および解釈 -との両方のいくつかの利点と欠点を兼ね備えています。JITコンパイルは、コンパイルされたコードの速度と解釈の柔軟性を兼ね備えています。
JVMで使用されるJITを考えてみましょう、
たとえば、HotSpot JVM JITコンパイラは動的な最適化を生成します。つまり、Javaアプリケーションの実行中に最適化の決定を行い、基盤となるシステムアーキテクチャを対象とした高性能のネイティブマシン命令を生成します。
コンパイルするメソッドが選択されると、JVMはそのバイトコードをJust-In-Timeコンパイラー(JIT)にフィードします。JITは、メソッドを正しくコンパイルする前に、バイトコードのセマンティクスと構文を理解する必要があります。JITコンパイラーがメソッドを分析するのを助けるために、そのバイトコードは、最初にトレースツリーと呼ばれる内部表現で再構成されます。これは、バイトコードよりもマシンコードによく似ています。次に、メソッドのツリーに対して分析と最適化が実行されます。最後に、ツリーはネイティブコードに変換されます。
トレースツリーは、プログラミングコードのランタイムコンパイルで使用されるデータ構造です。トレースツリーは、ホットスポット中に実行されるコードを追跡してコンパイルする「ジャストインタイムコンパイラ」のタイプで使用されます。こちらをご覧ください。
参照:
非JITコンパイラはソースコードを受け取り、コンパイル時にマシン固有のバイトコードに変換します。JITコンパイラーは、コンパイル時に生成されたマシンに依存しないバイトコードを受け取り、実行時にそれをマシン固有のバイトコードに変換します。Javaが使用するJITコンパイラーは、単一のバイナリーを変更せずに多数のプラットフォームで実行できるようにするものです。
バイトコードの20%が80%の時間使用されます。JITコンパイラーはこれらの統計を取得し、インラインメソッドを追加したり、未使用のロックを削除したり、そのマシンに固有のバイトコードを作成したりすることで、バイトコードのこの20%を最適化して高速に実行します。私はこの記事から引用していますが、便利だと思いました。http://java.dzone.com/articles/just-time-compiler-jit-hotspot
JITは、いくつかのJVM実装の実行エンジンを指します。1つは高速ですが、より多くのメモリを必要とし、ジャストインタイムコンパイラです。このスキームでは、メソッドが初めて呼び出されたときに、メソッドのバイトコードがネイティブマシンコードにコンパイルされます。次に、メソッドのネイティブマシンコードがキャッシュされるので、次に同じメソッドが呼び出されたときに再利用できます。
JVMは、パフォーマンス上の理由から、実行時にコンパイルステップを実際に実行します。つまり、Javaにはコンパイルと実行が完全に分離されていません。まず、Javaソースコードからバイトコードへのいわゆる静的コンパイルを行います。次に、このバイトコードがJVMに渡されて実行されます。ただし、バイトコードの実行は遅いため、JVMはバイトコードの実行頻度を測定し、非常に頻繁に実行されるコードの「ホットスポット」を検出すると、バイトコードから「ホットスポット」コードのマシンコード(ホットスポットプロファイラー)への動的コンパイルを実行します。したがって、今日のJavaプログラムは、マシンコードの実行によって効果的に実行されます。