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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

4回答

10859閲覧

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

mr0237

総合スコア164

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/05/07 15:18

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

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

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

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

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

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

つまり、

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

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

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

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

よろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

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

実行時コンパイラ - Wikipedia

例えばループ処理で

java

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

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

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

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

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

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

投稿2017/05/07 15:40

編集2017/05/07 15:48
mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mpyw

2017/05/07 15:44

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

0

ベストアンサー

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

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

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

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

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

投稿2017/05/08 02:34

otn

総合スコア84499

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mr0237

2017/05/08 13:39

じゃあつまり、 「ソースコード」→「バイトコード」→「機械語」←この3つではなく 「ソースコード」→「バイトコード」→「JVM」→「機械語」←この4つのプロセスで実行されるというのが正しいのでしょうか? 「バイトコード」→「JVM」に変換する際は「インタプリタ方式」で変換しますが、 「JVM」→「機械語」に変換する際は「コンパイラ方式」(おおざっぱに)で変換するのですか?
otn

2017/05/08 14:17

データ(コード)と実行する仕組みがごっちゃになっています。仕組みを= [ ]=> で表すと、 「ソースコード」===[Javaコンパイラ]==>「バイトコード」===[JVM]==>実行結果 「ソースコード」===[Javaコンパイラ]==>「バイトコード」===[JITコンパイラ]==>「機械語」===[CPU]==>実行結果 JVMというのはバイトコードインタプリタ(JITコンパイラ内蔵)のことです。 まずは、JITコンパイラの絡まない、純粋なインタプリタと、コンパイラのそれぞれの仕組みをきっちり理解してから、JITコンパイラありのインタプリタの理解に取り組んだ方が良いと思います。
guest

0

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

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

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

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

  1. JIT

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

  1. 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の実装によって正確にいつのタイミングで機械語へ変換されるかは違うということになります。

投稿2017/05/07 18:14

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

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

投稿2017/05/07 15:44

編集2017/05/07 15:44
swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問