質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.90%

「バイトコード」→「機械語」に変換して実行する方式が2つある?

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 6,923

mr0237

score 162

頭があれで、説明が下手ですいませんが、Javaの言語は「ソースコード」→「バイトコード」→「機械語」という順番で変換されて実行されますが、

「ソースコード」→「バイトコード」に変換する際は「コンパイラ方式」で変換
「バイトコード」→「機械語」に変換する際は「インタプリタ方式」で変換

という2つの方式を使って実行されていくと思いますが、

このページ「バイトコードの実行方式」を見てみると

・バイトコードをインタプリタで逐次解析しながら、「JVM」という仮想マシン上で実行。
・バイトコードの読み込み時に、JITコンパイラがバイトコードを機械語にコンパイルして実行。

と書かれていますが、一つ目の「バイトコードをインタプリタで逐次解析」のところはわかりますが、
もう一つの「バイトコードの読み込み時に、JITコンパイラがバイトコードを機械語にコンパイルして実行。」というのは
これはどういうことでしょうか?

つまり、

「バイトコードを機械語に変換する方式としてインタプリタで実行
「バイトコードを機械語に変換する方式としてコンパイラで実行

↑この2つのことを指すのでしょうか?

もし、この2種類があったとしたら、どんなときにどのタイミングで方式(インタプリタ・コンパイラ)を変えるのでしょうか?

それとも同時並行で実行するのでしょうか?

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+4

JITコンパイルについて調べれば解決する問題ですね。

実行時コンパイラ - Wikipedia

例えばループ処理で

int sum = 0;
for (int i = 1; i <= 10; ++i) {
   sum += i;
}

みたいなコードを書いたとき,コンパイラによって

sumに0を代入
iに1を代入
i<=10を計算
もし↑が偽なら処理を終わる
sumにiを代入
iをインクリメント
最初に戻る

のようなバイトコードが吐かれるはずです。これをインタプリタが1個ずつ読み取り,それに対応する処理が機械語レベルで実行されます。但し,最近のインタプリタは賢いので,

「この部分何回も繰り返してるし,毎回読み取って実行しなくても全部まとめて最初から機械語にしちゃったほうが効率的じゃね?」

という判断をして,インタプリタが動いている最中に,複数個のバイトコードをまとめて一気に機械語に変換する処理を行ってくれることがあります。これがJITコンパイルと呼ばれるものです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/08 00:44

    インタプリタ系の言語で,標準の処理系がJITコンパイル機能を持っているものとして有名なのはJavaScriptやRubyです。標準ではありませんが,PyPy(RPythonでPythonを実行する特殊な処理系)やHHVM(Facebookが開発したPHPライクなHackと呼ばれる言語の処理系)も有名です。

    キャンセル

checkベストアンサー

+3

「バイトコード」→「機械語」に変換する際は「インタプリタ方式」で変換 

ここから間違っています。インタプリタは機械語に変換などしません。
インタプリタというプログラムが、バイトコードをデータとして読み取って、バイトコードをJavaVMの命令として解釈(インタプリット)し、その解釈した通りに処理します。

これだと多数回の繰り返し処理などで繰り返す度に解釈処理を行うため、効率が悪いので、解釈実行処理の代わりに解釈して機械語に変換してからその機械語を呼び出すようにした物が、JITコンパイラです。
細かいところを無視して丸めた話にすると、
★一度しか実行しない処理
・・・・・インタプリタ: 解釈→実行
・・・・・JITコンパイラ: 解釈→機械語変換→実行
★ループで1万回実行する処理
・・・・・インタプリタ: (解釈→実行)×10000
・・・・・JITコンパイラ: 解釈→機械語変換→(実行)×10000

JITコンパイラの詳細は他の方の回答参照。

なお、上記で「インタプリタ」と書いたのはJITコンパイル機能を持たない純粋なインタプリタのことです。実際には、JITコンパイル機能を内蔵したものもインタプリタと呼ばれます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/08 22:39

    じゃあつまり、
    「ソースコード」→「バイトコード」→「機械語」←この3つではなく

    「ソースコード」→「バイトコード」→「JVM」→「機械語」←この4つのプロセスで実行されるというのが正しいのでしょうか?

    「バイトコード」→「JVM」に変換する際は「インタプリタ方式」で変換しますが、
    「JVM」→「機械語」に変換する際は「コンパイラ方式」(おおざっぱに)で変換するのですか?

    キャンセル

  • 2017/05/08 23:17

    データ(コード)と実行する仕組みがごっちゃになっています。仕組みを= [ ]=> で表すと、
    「ソースコード」===[Javaコンパイラ]==>「バイトコード」===[JVM]==>実行結果
    「ソースコード」===[Javaコンパイラ]==>「バイトコード」===[JITコンパイラ]==>「機械語」===[CPU]==>実行結果

    JVMというのはバイトコードインタプリタ(JITコンパイラ内蔵)のことです。

    まずは、JITコンパイラの絡まない、純粋なインタプリタと、コンパイラのそれぞれの仕組みをきっちり理解してから、JITコンパイラありのインタプリタの理解に取り組んだ方が良いと思います。

    キャンセル

+2

「バイトコードを機械語に変換する方式としてインタプリタで実行」
「バイトコードを機械語に変換する方式としてコンパイラで実行」
↑この2つのことを指すのでしょうか? 

NOです。Javaではコンパイラーと呼ぶべきものはjavacしかありません。javacはbyte codeのみ生成するものであり機械語を生成することはありません。結局javaで機械語に変換するのは、JVMがプログラムを実行する際にあるタイミングで行うということになります。

JITはJust-In-Timeコンパイラーのことなので、「事前に機械語に変換するのではなく」「プログラムを実際に動かしたその時に機械語に変換する」方式であると言えますが、自分も正確な契機は曖昧でしたのでとあるページをみてみました。このページでは単なるJITとHotSpotを異なる方式として説明していますが、内容としては分かりやすいと思います。以下、このページでのJIT/HostSpotの定義で考えることにすれば、

  1. JIT
    クラスファイルがロードされた後、その中に含まれる任意のメソッドが初めて呼び出されるときにそのメソッドのbyte codeを機械語に変換しそれを実行する。上のページの説明ではJVM上にbyte codeインタープリタはなくていいように見えますね。つまり初めて実行する契機で必ず機械語が生成されるので。

  2. HotSpot
    こちらはクラスファイルがロードされた後に、メソッドが初めて呼び出されたときには機械語へ翻訳せずにJVMがbyte codeインタープリタとして動作します。また実行を継続している過程でプロファイリングを行い(例えばメソッド呼び出し回数などのプロファイリング?)「どうもこのメソッドは頻繁に呼び出されてるみたいだ」とJVMが判断したタイミングで初めて機械語へ翻訳されます。これはmpywさんが説明されている方式の方ですね。

現在Oracleから提供されているJVMはHotSpot方式です

$ java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode) <=この行に出てる


これを用いるのであれば後者で動いていると解釈すればよいと思います。一方世の中にはOracle以外が提供するJVMも存在し、その中で2.ではなく1.の方式のものもあるかも知れません。要するにJVMの実装によって正確にいつのタイミングで機械語へ変換されるかは違うということになります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ここでいう「JITコンパイラ」を調べると、実行時コンパイラという名称の略称のようです。
リンクの「インタプリタ方式との比較」を見てもらうとわかりますが、インタプリタもJITコンパイラも実行時に機械語に変換していることには変わりないのですが、インタプリタは行ごと、JITコンパイラはクラスなどのかたまりごとに変換を行います。「バイトコードの実行方式」の2種類の差はそのままこれです。
で、その次の行では

引用テキストJavaの登場当初はインタプリタ方式で実行されていましたが、現在ではJITコンパイラの方が主流となっています。

と、きちんと説明されています。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.90%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る