Javaはコンパイル済みまたは解釈済みのプログラミング言語ですか?


169

過去にはプログラミング言語としてC ++を使用していました。C ++で書かれたコードは、オブジェクトコード "machine code"になるまでコンパイルプロセスを経ることを知っています。

その点でJavaがどのように機能するか知りたいのですが。ユーザーが記述したJavaコードはコンピューターでどのように実行されますか?


14
C ++は解釈できます。そこにいくつかのCインタプリタがあります。
トム・ホーティン-タックライン09

回答:


220

通常、Java実装は2段階のコンパイルプロセスを使用します。Javaソースコードは、Javaコンパイラによってバイトコードにコンパイルされます。バイトコードは、Java仮想マシン(JVM)によって実行されます。最新のJVMは、ジャストインタイム(JIT)コンパイルと呼ばれる手法を使用して、バイトコードを実行時にハードウェアCPUがオンザフライで理解できるネイティブ命令にコンパイルします。

JVMの一部の実装では、バイトコードをJITでコンパイルしてマシンコードに変換し、直接実行するのではなく、バイトコードを解釈する場合があります。これは「インタプリタ」と見なされていますが、高レベルのソースコードを読み取って実行するインタプリタとはかなり異なります(つまり、この場合、Javaソースコードは直接解釈されず、バイトコード、Javaコンパイラの出力は解釈されます)。

Javaを事前にネイティブコードにコンパイルして、結果のバイナリを実行することは技術的に可能です。Javaコードを直接解釈することもできます。

要約すると、実行環境に応じて、バイトコードは次のようになります。

  • 事前にコンパイルされ、ネイティブコードとして実行されます(ほとんどのC ++コンパイラと同様)。
  • ジャストインタイムでコンパイルして実行
  • 解釈された
  • サポートされているプロセッサによって直接実行されます(バイトコードは一部のCPUのネイティブ命令セットです)

20
実際、一部のHotSpot JVMはバイトコードを解釈することから始まり、コンパイルする価値があるものを見つけて、コードの実行方法に関する統計を収集した後で、それらをネイティブコードにコンパイルします。たとえば、各条件付きブランチで取られる最も一般的なパスを理解するために。
スティーブンC

1
したがって、「ホットスポット」という用語は、最適化を得るために、頻繁に実行されているものに対して実行します。
正午シルク

4
HotSpotで-Xcompを使用してインタープリターをオフに切り替えることができます。アプリケーションを試してみて、それが悪い考えであるかどうかを確認する価値があります。
トム・ホーティン-タックライン09

1
「Sun HotSpot JVMの現在のバージョンは、ジャストインタイム(JIT)コンパイルと呼ばれる手法を使用して、実行時にオンザフライでCPUが理解するネイティブ命令にバイトコードをコンパイルします。」JVMはインタープリターであるという印象を受けましたが、バイトコードをさらにコンパイルすることを示唆しています。私は混乱しています。また、実行時にオンザフライで実行するように記述されています。誰かもこれを説明できますか?
アナンド

Javaはインタプリタ言語であるため、パフォーマンスやJavaアプリケーションの実行にどのように影響するか
NAND

93

ここに画像の説明を入力してください

Javaで書かれたコードは:

  • 上の画像の左側のセクションに示すように、最初にjavacと呼ばれるプログラムによってバイトコードにコンパイルされます。
  • 次に、上の画像の右側のセクションに示すように、javaと呼ばれる別のプログラムがJavaランタイム環境を起動し、Javaインタープリター/ JITコンパイラーを使用してバイトコードをコンパイルまたは解釈します。

Javaはいつバイトコードを解釈し、いつコンパイルしますか?アプリケーションコードは最初に解釈されますが、JVMは頻繁に実行されるバイトコードのシーケンスを監視し、ハードウェアで直接実行できるようにそれらをマシンコードに変換します。数回しか実行されないバイトコードの場合、これによりコンパイル時間が節約され、初期待ち時間が短縮されます。頻繁に実行されるバイトコードの場合、JITコンパイルは、低速の解釈の初期段階の後、高速で実行するために使用されます。さらに、プログラムはほとんどのコードの実行にほとんどの時間を費やすため、コンパイル時間の短縮は重要です。最後に、初期コードの解釈中に、コンパイル前に実行統計を収集できるため、最適化をより効果的に実行できます。


Javaが大量のメモリを使用するのは、キャッシュされたバイトコードが原因ですか?
ペドロゴルド2017

3
@sedulam:「大量のメモリ」はあいまいなステートメントです。Javaのメモリ管理は非常に単純です。3つの世代は、JVMがオブジェクトの作成と保守に使用するものです。この別のSOの答えはあなたに役立つかもしれません。
displayName

上記の説明では、理論的には、JITがマシンコードに変換しないと決定する.classファイルの一部が常に存在するため、C ++コンパイルコードは常に論理的に類似したJavaコードよりも高速になります。言い換えると、Javaは、C ++が実証したベアメタル実行速度をキャッチすることができません。これは正しい仮定ですか?
DevdattaK 2017年

@DevdattaK:C ++についてはあまり知りませんが、私が思うに、小規模で特殊なプログラムの場合、Javaは結果がより速くなる可能性があります。なぜなら、利用可能なスピードがあまりないコードの部分をコンパイルする時間を無駄にしないからです。
displayName

1
@DevdattaKあなたの仮定は、このwikiページen.m.wikipedia.org/wiki/Java_performance?wprov=sfla1で説明されています 。要するに、常にそうであるとは限りません。
Sundar Rajan、2018年

57

「解釈された言語」または「コンパイルされた言語」という用語は、どのプログラミング言語でも解釈および/またはコンパイルできるため、意味がありません。

Javaの既存の実装については、ほとんどがバイトコードへのコンパイル手順を含むため、コンパイルが含まれます。ランタイムはバイトコードを動的にロードすることもできるため、常に何らかの形式のバイトコードインタープリターが必要です。そのインタープリターは、ネイティブコードへのコンパイルを内部的に使用する場合としない場合があります。

最近、部分ジャストインタイムコンパイルは、かつて「解釈済み」と見なされていた多くの言語、たとえばJavaScriptで使用されています。


5
また、GoogleのV8 JavaScript実行エンジンは、部分的なジャストインタイムのコンパイルを実行するだけではありません。それは常に、実際には、V8もしない、ネイティブコードにコンパイルする必要がありインタプリタを。それは持っているだけで、コンパイラ(マキシンに類似するが、マキシンV8とは異なり一つだけのコンパイラを持っています)。これらの3つの例(GCJ、Maxine、V8)はすべて、あなたの主張をより強く証明します。インタープリター型言語やコンパイル済み言語などはありません。言語は解釈またはコンパイルされません。言語はまさにそれです(それ実際にはShriram Krishnamurthiによる引用です)。
イェルクWミッターク

3
なぜあなたはJavaの質問でJavaScriptについて話しているのですか?
Koray Tugay

1
@KorayTugay例として。私は、JavaとJavascriptの名前の最初の4文字以外に共通点があることをほのめかしたくありません。
starblue 2017年

インタプリタ言語とコンパイル済み言語の少なくとも違いは、コンパイル済み言語バイナリが実行フローをいつでも変更できないことを意味するのではなく、インタプリタ言語は現在の関数の動作の一部に非常に従順です。Cのライブラリはオプションですが、他の言語では、更新できるCバイナリ拡張または別のプラットフォームで完全に異なるコードにすることができる配列オブジェクトはありません。スクリプト言語は両方で実行できますが、コンパイルされた言語では異なるバイナリを実行する必要があります
Eaton Emmerich

53

Javaはバイトコードにコンパイルされ、バイトコードがJava VMに渡されて解釈されます。


33
...しかし、厳密には正確ではありません。
スティーブンC

2
JVMはバイトコードを「解釈」しないことを選択する場合があります。JITコンパイルして直接実行できます。
Mehrdad Afshari、

1
JITは技術的に直接実行していません。実行方法を覚えているだけです。
cletus 09

Mehrdad:同意しました。JITまではJITである可能性があるため、ここではJITの可能性がある操作については説明しませんでした。とにかく答えを単純にしていたのです:)
正午9

7
cletus:JIT 、直接実行されます。JITはバイトコード(完全なメソッドなど)の一部を読み取り、マシンコードにコンパイルしてジャンプします。
Mehrdad Afshari、

12

Javaはコンパイルされたプログラミング言語ですが、実行可能なマシンコードに直接コンパイルするのではなく、JVMバイトコードと呼ばれる中間バイナリ形式にコンパイルします。次に、バイトコードがコンパイルおよび/または解釈され、プログラムが実行されます。


11

両方の種類。まず、Javaでバイトコードにコンパイルし(一部は「変換」と言う方がいいでしょう)、バイトコードをコンパイルするか、JITのムードに応じて解釈します。


32
それは気分を発展させるための高度なソフトウェアです:)
Thorarin

5
JITは確かに非常に洗練されたソフトウェアであり、ランタイム情報に基づいて最適化を行うことができます(プロファイラーなど)。事前にプログラム)。しかし、おそらく実際には気分はありません... :-)
Jesper

5

Javaはコンパイルと解釈の両方を行い、

Javaでは、プログラムは実行可能ファイルにコンパイルされません。それらはバイトコードにコンパイルされ(前述のとおり)、JVM(Java仮想マシン)が実行時に解釈/実行します。javacコンパイラを使用すると、Javaソースコードがバイトコードにコンパイルされます。バイトコードは、ファイル拡張子.classでディスクに保存されます

プログラムを実行するときに、バイトコードが変換されます。バイトコード、ジャストインタイム(JIT)コンパイラを使用して変換できます。その結果、マシンコードがメモリに送られ、実行されます。

Javacは、JavaコードをバイトコードにコンパイルするJavaコンパイラです。JVMは、バイトコードを実行/解釈/ネイティブコードに変換するJava仮想マシンです。Javaではインタプリタ言語と見なされていますが、バイトコードがJVMにある場合、JIT(ジャストインタイム)コンパイルを使用する場合があります。JITコンパイラーは、バイトコードを多くのセクションで(または完全に、まれに)読み取って動的にマシンコードにコンパイルするため、プログラムをより高速に実行し、キャッシュして後で再コンパイルすることなく再利用できます。したがって、JITコンパイルでは、コンパイルされたコードの速度と解釈の柔軟性が組み合わされています。

インタプリタ型言語は、その実装の大部分は、以前に機械語命令にプログラムをコンパイルすることなく、直接、自由に命令を実行しているの言語プログラミングの一種です。インタプリタはプログラムを直接実行し、各ステートメントを、すでにマシンコードにコンパイルされている1つ以上のサブルーチンのシーケンスに変換します。

コンパイルされた言語は、その実装典型的にコンパイラ(ソースコードからマシンコードを生成する翻訳者)であり、しないインタープリタ(無プリランタイム変換が行われていないソースコードの段階的エグゼキュータ)プログラミング言語であります

Javaのような最新のプログラミング言語実装では、プラットフォームが両方のオプションを提供することがますます一般的になっています。


「バイトコードをしなければならないこと」というよりも、変換され「ている変換します」。Java仕様ではバイトコードが定義されています。そのバイトコードが(a)ハードウェア直接実行されるか、(b)インタープリターを介して実行されるか、(c)事前にコンパイルされるか、または(d)実行時に部分的にコンパイルされるかは、実装の詳細としてすべて残されます。これらの4つのオプションはすべて、実際のさまざまなJava実装で実際に使用されています。
バジルブルク2018

これを指摘してくれてありがとう。それで、バイトコードがマシンコードに変換されない場合はどうなりますか?バイトコードが一部のプロセッサのネイティブ命令セットであり、変換の必要がないシナリオを考えることができます。それとも何か不足していますか?
プライム

私が与えたリンクをクリックのJazelle DBX(直接バイトコード実行) JVMバイトコードのサブセットは、テクノロジー、ある CPU(ちょっと-みかん)のネイティブマシン命令を。それがなければ、バイトコードから生成されたマシンコードを(a)インタプリタから(オンザフライで)、(b)コンパイラから事前に、または(c)オンザフライでジャストインタイムコンパイラ(最初に解釈され、次に実行時にコンパイルおよびキャッシュされる場合があります)。
バジルブルク2018

-2

Javaは、スタックベースのJava仮想マシンと呼ばれるプラットフォームを対象としたバイトコンパイル言語であり、多くのプラットフォームで非常に高速に実装されています。


1
「バイトコンパイル」とはどういう意味ですか?
Jesper、

2
@Jesper:「バイトコンパイル済み」は通常「バイトコードにコンパイル済み」を意味します。"バイトコード"は、あらゆる種類の非テキスト中間コード(一般にマシン実行可能ではない)をカバーする一般的な用語です。
グレッグヒューギル

-3

引用:https : //blogs.oracle.com/ask-arun/entry/run_your_java_applications_faster

アプリケーション開発者は、今日の市場で入手可能なさまざまなOSのいずれかでアプリケーションコードを開発できます。この段階では、Java言語はOSに依存していません。Javaアプリケーション開発者が書いた素晴らしいソースコードは、Javaの用語でクライアントサイドコンパイルと呼ばれるJavaバイトコードにコンパイルされるようになりました。Java Byteコードへのこのコンパイルは、Java開発者が「1度書く」ことを可能にするものです。Java Byteコードは、互換性のあるすべてのOSおよびサーバーで実行できるため、ソースコードはOS /サーバーに依存しません。Java Byteコードの作成後、Javaアプリケーションと基盤となるOS /サーバー間の相互作用はより密接になります。旅は続きます-エンタープライズアプリケーションフレームワークは、Java仮想マシン(JVM)またはJavaランタイム環境(JRE)として知られるランタイム環境でこれらのJavaバイトコードを実行します。JVMは、OSとサーバーが提供するリソースを利用するため、基盤となるOSとハードウェアと密接な関係があります。Java Byteコードは、プラットフォーム固有の機械語実行可能コードにコンパイルされるようになりました。これはサーバー側コンパイルと呼ばれます。

したがって、Javaは間違いなくコンパイルされた言語だと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.