web-dev-qa-db-ja.com

Javaバイトコードは解釈されますか?

解釈の定義(間違っている場合は修正してください)は、次のようにコードを解析します。

1-​​=現在解析されている行を中間言語に翻訳します。 2-翻訳された行を実行します。 -次の行に移動します。 4-翻訳します。 5-実行します。等々。

もしそうなら、なぜ人々はJVMを解釈 Java Bytecode?と言うのはなぜですかexecute itです。バイトコードはすでに翻訳されています。 Javaソースコードなので、さらに翻訳する必要はありません。

解釈という用語が含まれるのはなぜですか?

JVM executes Bytecode line by lineのためにこの用語が使用されている場合、どの実行でもそれが実行されると思います。実行可能なコードを上から下に実行します。なぜ解釈という用語を使用するのですか?

解釈何とは対照的ですか?

6
NPElover

プロセッサがマシン命令を実行します。それらはプロセッサが理解する唯一のものです。

Javaバイトコードは、一連の操作を表現するための中間的でコンパクトな方法です(より良い用語が必要なため)。プロセッサはこれらを直接実行できません

Java仮想マシンはバイトコード操作のストリームを処理し、プロセッサが実行する一連のマシン命令に解釈します。

これは、Pythonインタプリタが入力に対して実行するプロセスと非常に似ています。Pythonスクリプト。これは重要ではありませんJavaバイトコードは実行の高速化に役立つバイナリ形式であり、Pythonスクリプトはテキストファイルです。Pythonでも.pyモジュールをバイナリに処理します同じ理由で.pycフォーム。より根本的な違いは、Javaバイトコードは、オブジェクトに対するメソッド呼び出しの解決、型のチェックなど、より徹底的な前処理ステップを経ているため、 JVMはそれを行う必要はありません。

このVMプロセスは、コンパイルされたJavaがX86プロセッサを搭載しているかどうかに関係なく、あらゆるコンピュータに移植できるようにするものですARMまたはそのほか-そのプラットフォーム用のJVMがある限り、JVMの異なるバージョンはすべて同じバイトコードを解釈しますが、プロセッサに適切なマシン命令を生成します。

詳細については、Javaのような仮想マシンとCPythonのようなインタープリターとの違いについての優れた説明を参照してください。

https://stackoverflow.com/questions/441824/Java-virtual-machine-vs-python-interpreter-parlance

9
WillW

解釈の定義(間違っている場合は訂正してください)は、次のようにコードを解析します。

  1. 現在解析されている行をいくつかの中間言語に翻訳します。
  2. 翻訳された行を実行します。
  3. 次の行に移動します。
  4. 翻訳してください。
  5. それを実行します。等々。

これは有効な定義ではありません。インタプリタを実装する1つの方法について説明していますが、他の方法は除外しています。ほとんどの通訳はそのような時にラインを操作しません。中間フォームを実際に実行する前に、ソースコードから中間フォームに変換するのが一般的です。

また、「中間形式」というフレーズでさえ、中間形式の後にの後のコードに他の形式があることを示唆しているため、誤っている可能性があります。

もしそうなら、JVMがJava Bytecodeを解釈するのはなぜだと人々が言うのでしょうか?それが実行することはそれを実行することです。

解釈は実行の一形態です。したがって、矛盾はありません。

何ではなく解釈?

バイトコードをネイティブコードにコンパイルしてネイティブコードを実行するのではなく。これはtypicaltypicalJava implementations ...何らかの方法で発生することです。

typicalJVMでは、バイトコードは最初から解釈されます。少しすると、JITコンパイラーはそれらを直接実行できるネイティブコードにコンパイルします。その他のモードは次のとおりです。

  • 常にバイトコードを解釈します。例えばJava -intを使用
  • コンパイルの前に;例えばgcjを使用します。
  • ロード時のコンパイル...バイトローダーは、クラスローダーによって読み込まれるときにネイティブコードにコンパイルされます。例えばJNodeはこれを行います。

フォローアップ質問

JIT実行は、実行中に各行をコンパイルすることを意味しますよね?もしそうなら、それは解釈とどう違うのですか?

まず、それは正しくありません:

  • 「JIT実行」というものはありません。人々がそれを言うとき、彼らは本当に「JITコンパイルと実行」を意味します...そして彼らはそれを綴っていません。

  • JITコンパイルは一度に1行ずつ実行されません。通常、メソッドは一度に実行されます。

そして、違いはそれが何をしているのかです。 JITコンパイラは、バイトコードをネイティブコードにコンパイルする役割を果たします。バイトコードは実行されません。バイトコードの実行は、バイトコードを(JITコンパイルされる前に)解釈するか、JITコンパイラが生成したネイティブコードを実行することによって行われます。

4
Stephen C

実装によって異なります。

Javaバイトコードはマシンコードと同じではありません。ほとんどのアーキテクチャで使用されているものと非常によく似ているため、マシンコードへの変換は比較的簡単ですが、私は知りません。実際にネイティブに実行するマシン。

Java仕様は、仕様が示すとおりの結果である限り、コードがどのように実行されるかを気にしません。しかし、ネイティブで実行しない場合は、次に、何らかの方法でそれを翻訳する必要があります。あなたはcan解釈を使用してこれを行います。それが初期のJVMが機能していた方法ですが、この手法はより最近の傾向です。今日では、それを事前コードまたはジャストインタイムのいずれかでネイティブコードにコンパイルし、バイトコードの代わりにそれを実行することがより一般的です。

1
The Spooniest

解釈:これは、小さなコードを取り出し、それが何をするのかを理解してから実行することを意味します。コードのごく一部は「プレーンテキスト」のソースコードの場合がありますが、トークン化されたある種のコード、バイトコードのようなもの、または異なるCPUのネイティブ命令の場合もあります。ここでの重要な違いは、実行されているCPUのネイティブコードに変換されなかったことを解釈するためです。

コンパイル:これは、ソースコードをネイティブコードに変換することを意味します。ほとんどの人が「コンパイラ」について考えるとき、プレーンテキストのソースコードをネイティブコードに変換するツールを考えます(実行前にコンパイルされるため、「エンド・オブ・タイム・コンパイル」として知られています-多くの場合、エンドユーザーが受け取る前でさえ)。これがコンパイルする唯一の方法ではありません。事前コンパイルの主な利点は、エンドユーザーがかかる時間を気にすることなく、コンパイラがコードを最適化するのに多くの時間を費やすことができることです。

JITコンパイル:これはコンパイルのさまざまなケースの1つです(注:JITは「ジャストインタイム」であり、別の人が代わりにこの動的変換を呼び出します)。この場合、小さなコードを実行する必要があるまで待ってから、その小さなピースをネイティブコードにコンパイルして実行します。次に、次の小さなコードを探します。以前にコンパイルされた小さな断片をキャッシュすることにより、プログラムの実行中にほとんどのプログラムをコンパイルすることになります。頻繁に実行されるコードの場合、これは解釈よりもはるかに高速です。ただし、コードが解釈されるよりも遅い場合にのみ実行されます。

Javaの場合、まず、プレーンテキストのソースコードが、事前のコンパイラを使用してバイトコードにコンパイルされます。ここで多くの最適化が行われます。その後、バイトコードはJava仮想マシン(JVM)によって実行されます。

JVMの古い実装は、バイトコードの解釈に使用されていました(遅い)。最近のJVMは、あまり実行されないバイトコードを解釈し(正当化されない場合のコンパイルのオーバーヘッドを回避するため)、頻繁に実行されるコードのJITコンパイルも実行します(重要な部分のネイティブ速度に近づくため)。

基本的には(最新の実装の場合)、どちらかではありません。「前倒し」の後に、解釈されたコンパイルとJITコンパイルが混在しています。

1
Brendan

解釈の定義(間違っている場合は修正してください)は、次のようにコードを解析します。

1-現在解析されている行をいくつかの中間言語に翻訳します。 2-翻訳された行を実行します。 3-次の行に移動します。 4-それを翻訳します。 5-それを実行します。等々。

「解釈」のあなたの定義は間違っていると思います-解釈には(必然的に)翻訳ステップはありません。だからそれはする必要があります:

  1. コードのチャンクを読み取る
  2. そのコードのチャンクを実行します
  3. コードの次のチャンクを読む
  4. 次のチャンクを実行する
  5. ...立ち止まるな

JVMバイトコードインタープリターの場合、「チャンク」は単一のバイトコードです。より伝統的なインタプリタ言語では、「チャンク」は行である場合があります。 「実行」ステップでは、チャンクのILを生成してからそのILを解釈する必要があります。この場合、2つのインタープリターがあり、高レベルのインタープリターが低レベルのインタープリターを呼び出します。

1
Chris Dodd

Javaバイトコードは言語です。言語は解釈またはコンパイルされません。彼らはただあるです。解釈とコンパイルは、インタプリタまたはコンパイラ(duh!)、つまりその言語のimplementationの特性です。

解釈されたJVMの実装(たとえば、Sun JVMの初期バージョンJava 1.2)以前)、JVMのコンパイル済み実装(たとえば、Maxineの初期バージョン)がありますが、最も一般的に使用される実装、Sun/Oracle HotSpot JVMは実際には両方です。最初にバイトコードを解釈して統計を収集し、次にそれらの統計から導出された最適化情報を使用してパフォーマンスが重要な部分をコンパイルします。

0
Jörg W Mittag