私は、Javaソースコードが「バイトコード」にコンパイルされ、JITによって「マシンコード」に再度「コンパイル」されることを読みました。つまり、ソースコードは最初にプラットフォームに依存しないバイトコードにコンパイルされ、次にマシン固有のコードに再度コンパイルされます。では、なぜインタープリター言語とコンパイル言語の両方と呼ばれるのでしょうか。解釈はどこで行われますか?
7 に答える
ここで少し誤解があります。
通常、java compiler( javac
) は Java コードをバイトコードにコンパイルし、java interpreter( java
) はこれらのバイトコードを (1 行ずつ) 解釈し、機械語に変換して実行します。
JIT(Just in time)
コンパイラは少し異なる概念です。JVM は、関数が実行された回数を保持します。制限を超えると、JIT が登場します。Javaコードは機械語に直接コンパイルされ、そこでその機能を実行するために使用されます。
Java はプログラミング言語です。
Java プログラムがどのように動作するかを定義する仕様 (JLS) があります。
言語自体として、さまざまなプラットフォームで実行する方法を指定していません。JIT の有無にかかわらず、実行方法は完全に実装ベースです。
明日、JIT コンパイルをまったく行わない Java ランタイムを作成する場合、Java インタープリターを呼び出すことができます。
Java バイトコードをアセンブリとして使用する Java マシン (そして人々が真剣に作成したもの) を使用する場合、厳密にコンパイルされた Java と呼ぶことができます。
他の多くの言語はこれを行います:
- Pythonはインタープリター言語ですか? (CPython) それとも JITed (PyPy) ですか?
- Lua は解釈されますか (古い lua インタープリター)、それともコンパイルされますか (LuaJIT)?
- JavaScript は解釈されますか (IE6 スタイル)、それともコンパイルされますか (v8)?
正確を期すために、これは Java プログラミング言語の問題ではなく、JVM の機能の問題であることを明確にしましょう。
JVM の最初の実装では、JIT は存在せず、バイトコードは常に解釈されていました。これは、コンパイルされたコードを物理マシンや Java を実行している OS から独立させるという設計上の決定によるもので、現在でも有効です。
後の改良として、実行を高速化するために JIT が JVM 実装に導入されましたが、バイトコードは引き続き有効であり、バイナリに変換される前にすべての検証に合格する必要があります。このようにして、プラットフォームの独立性、すべての健全性とセキュリティ チェックを維持し、パフォーマンスを向上させます。
Java はハイブリッド言語です。つまり、コンパイル済み (事前に作業を行う) とインタープリテッド (受信側で作業を行う) の両方です。
バイトコードはJavaにとってIL(中間言語)です。Java ソースコードは によってバイトコードにコンパイルされjavac
ます。このバイト コードは、JIT ( Just - I n - Time ) コンパイルと呼ばれる機械語に再度コンパイルされることがあります。
JIT コンパイルは、実行前ではなく、プログラムの実行中 (実行時) にコンパイルを含むコンピューター コードを実行する方法です。ソース
JVM (JIT なし)は、次のように Java 中間言語バイト コードをネイティブ マシン言語に解釈します。
JVM は抽象的なコンピューティング マシンであり、いくつかの実装があります。
HotSpot (インタープリター + JIT コンパイラー) : プライマリ リファレンス Java VM 実装。Oracle Java と OpenJDK の両方で使用されます。
JamVM (Interpreter) 他に比べて非常に小さい仮想マシンになるように開発されました。GNU クラスパスを使用するように設計されています。複数のアーキテクチャをサポートします。GPL。
ART (Interpreter + AOT compiler ie Ahead-of-time compilation) Android R un Timeは、Dalvik (インタープリター + JIT コンパイラー)に代わる Android オペレーティング システムで使用されるアプリケーション ランタイム環境です。
javac はコンパイラであり、Java コードをバイトコード (バイトコードを参照) に変換します。これは、JVM (Java 仮想マシン) があればどのマシンでも簡単に実行できます。インタプリタは Java バイトコードをマシンコードに変換します。
これには 2 つの目的があります。1 つ目は、コードが構文的にも意味的にも正しいことを確認することです。次に、コンパイル プロセスでバイトコードが生成されます。お気づきのように、これはアーキテクチャに依存しない中間言語であり、特定のマシン アーキテクチャの JVM によってネイティブ コードに解釈またはジャストインタイム コンパイルできます。バイトコードにコンパイルすることにより、コンパイルに関連するオーバーヘッドの多くを事前に処理できるため、事前に徹底的かつ厳密にチェックされたバイトコードからネイティブ コードを生成または解釈することを JVM に任せることができます。