web-dev-qa-db-ja.com

JITがバイトコードもコンパイルするのに、なぜJavaはコンパイルされた言語とインタープリター言語の両方であるのですか?

Javaソースコードは「バイトコード」にコンパイルされ、次にJITによって「マシンコード」に再び「コンパイル」されます。つまり、ソースコードは最初にプラットフォームにコンパイルされます。独立したバイトコードを作成してから、マシン固有のコードに再度コンパイルします。それでは、なぜそれが解釈言語とコンパイル言語の両方と呼ばれるのでしょうか。解釈はどこで行われるのでしょうか。

15
Ragul

ここには少し誤解があります。

通常の状況では、Javaコンパイラ(javac)はJavaコードをバイトコードにコンパイルし、Javaインタプリタ(Java)は、これらのバイトコードを(1行ずつ)解釈し、機械語に変換して実行します。

JIT(Just in time)コンパイラは少し異なる概念です。 JVMは、関数が実行された回数を維持します。制限を超えると、JITが登場します。 Javaコードは機械語に直接コンパイルされ、そこでその関数を実行するために使用されます。

18
Aniket Thakur

Javaはプログラミング言語です。

Javaプログラムがどのように動作するかを定義する仕様(JLS)があります。

言語自体として、さまざまなプラットフォームでどのように実行するかを指定していません。 JITの有無にかかわらず、実行方法は完全に実装ベースです。

  • 明日、JITコンパイルをまったく行わないJavaランタイムを作成した場合、Javaインタープリターを呼び出すことができます。

  • アセンブリとしてJavaバイトコードを使用するJavaマシン( そして人々は真剣にそれらを作った )を取ると、厳密にJavaを呼び出すことができます編集済み。

他の多くの言語がこれを行います:

  • pythonはインタープリタ型言語ですか? (CPython)またはそれはJITed(PyPy)ですか?
  • Luaは解釈されますか(古いluaインタープリター)、それともコンパイルされますか(LuaJIT)?
  • JavaScriptはインタープリター型(IE6スタイル)ですか、それともコンパイル済み(v8)ですか?
9

正確を期すために、これがJavaプログラミング言語の質問ではなく、JVM機能であることを明確にしましょう。

JVMの最初の実装では、JITは存在せず、バイトコードは常に解釈されていました。これは、コンパイルされたコードを物理マシンやJavaを実行しているOSから独立させるという設計上の決定によるものであり、現在でも有効です。

後の改良として、実行を高速化するためにJITがJVM実装に導入されましたが、バイトコードは引き続き有効であり、バイナリに変換される前にすべての検証に合格する必要があります。このようにして、プラットフォームの独立性、すべての健全性およびセキュリティチェックを維持し、パフォーマンスを向上させます。

3
Jorge_B

Javaはハイブリッド言語です。つまり、コンパイル済み(事前に行われる作業)と解釈済み(受信側で行われる作業)の両方です。

バイトコードはIL([〜#〜] i [〜#〜]中間[〜#〜] l [〜#〜]anguage)からJavaへ。 Javaソースコードはjavacによってバイトコードにコンパイルされます。このバイトコードは、JIT([〜# 〜] j [〜#〜]ust-[〜#〜] i [〜#〜]n- [〜#〜] t [〜#〜]ime)コンパイル。

JITコンパイルは、実行前ではなく、実行時にプログラムの実行中にコンパイルを伴うコンピューターコードを実行する方法です。 ソース

JVM(JITなし)は、Java中間言語のバイトコードをネイティブマシン言語に次のように解釈します。

enter image description here

ソース

JVMは抽象コンピューティングマシンであり、いくつかの実装があります。

  • HotSpot(インタプリタ+ JITコンパイラ):プライマリリファレンスJava VM実装。OracleJavaとOpenJDKの両方で使用されます。

  • JamVM(インタプリタ)他の仮想マシンと比較して非常に小さい仮想マシンとして開発されました。 GNUクラスパスを使用するように設計されています。いくつかのアーキテクチャをサポートしています。GPL。

  • [〜#〜] art [〜#〜](インタプリタ+ AOTコンパイラ、つまり事前コンパイル)[〜#〜] a [〜#〜]ndroid[〜#〜] r [〜#〜]un[〜#〜] t [〜#〜]imeは、Androidオペレーティングシステムの置き換えDalvik(インタプリタ+ JITコンパイラ)。

Java仮想マシン)のリスト

2
Premraj

javacはコンパイラであり、Javaコードをバイトコード(バイトコードを参照)に変換します。これは、JVM(Java仮想マシン)があれば、どのマシンでも簡単に実行できます。インタプリタはJavaバイトコードをマシンコードに変換します。

1
S. Panwar

他のプログラミング言語とは異なり、Javaはコンパイルされ、解釈される言語です。Java IDEはコンパイラおよびJVM(Java仮想マシンとして機能します) )インタプリタのように動作します。つまり、HelloなどのプログラムがHello.Javaとしてコンパイルされた後に保存され、このファイルをコンパイルした後、Hello.Class拡張ファイルがclass-file、byte-code、または中間コードとして呼び出されます。Byte-コードは特定のマシンに依存しないため、中間コードとも呼ばれます。このバイトコードをマシンコードまたはマシンが理解できる形式に変換するには、オペレーティングシステムごとに異なるJVMが使用されます。JIT(Just in Timeコンパイラ)はデフォルトで有効になっているJVMの一部は、バイトコードを「ジャストインタイム」でコンパイルするネイティブマシンコードにコンパイルします。

0

それは2つの目的を果たします。 1つ目は、コードが構文的および意味的に正しいことを確認することです。次に、コンパイルプロセスでバイトコードが生成されます。お気づきのとおり、これはアーキテクチャに依存しない中間言語であり、特定のマシンアーキテクチャ用にJVMによって解釈されるか、ネイティブコードにジャストインタイムでコンパイルされます。バイトコードにコンパイルすることにより、コンパイルに関連するオーバーヘッドの多くを事前に行うことができ、JVMは、事前に徹底的かつ厳密にチェックされたバイトコードからネイティブコードを生成したり、バイトコードを解釈したりできます。

0
Chris Mantle