FE EXAM

中間コード(バイトコード)

ソースコードと機械語の中間に位置する、仮想マシン向けの中間表現。

DIAGRAM
ソース
中間コード
仮想マシン
ソースコードHello.java人が書いたプログラム(高水準言語)コンパイル中間コード(バイトコード)Hello.classCPUに依存しない中間表現1つの中間コードを、各OSのVMが実行する仮想マシン(VM)中間コードを解釈・実行Windows各OS / CPU仮想マシン(VM)中間コードを解釈・実行macOS各OS / CPU仮想マシン(VM)中間コードを解釈・実行Linux各OS / CPUWrite Once, Run Anywhere — 1度書けば、VMがある環境ならどこでも動く
解説

📌
中間コードとは

ソース中間コード(中間)機械語ソースと機械語の「ちょうど中間」

中間コード(バイトコード)とは、人が書くソースコードと、CPUが直接実行する機械語の、ちょうど中間に位置する表現のことです。名前のとおり「中間」にあり、特定のCPU(=計算を行う頭脳。種類によって理解できる命令が違う)に依存しません。

身近な例で考えると、世界共通の「絵文字マニュアル」に似ています。日本語(ソース)を各国の言葉(機械語)にいきなり訳す代わりに、まず誰でも分かる絵文字(中間コード)にしておけば、各国にその絵文字を読める案内係(仮想マシン)がいるだけで内容が伝わります。

上の図解では、ソースコードがコンパイル(=翻訳)されて中間コードになり、その1つの中間コードが各OS(基本ソフト)上の仮想マシンで実行される流れを示しています。

⚙️
仮想マシンとの関係

中間コード渡す仮想マシン解釈・実行中間コードはVMが解釈して動かす

中間コードは、それ単体ではCPU上で直接動きません。仮想マシン(VM=Virtual Machine、中間コードを解釈して実行するソフトウェア)が間に入り、中間コードを読み取って実際の処理を行います。

代表的な組み合わせは次のとおりです。
Java:ソースをコンパイルしてバイトコード(.class)を作り、JVM(Java仮想マシン)が実行する
Python:実行時にバイトコード(.pyc)へ変換し、Pythonの仮想マシンが実行する
C#:中間言語(CIL)を作り、.NETの実行環境が実行する

ポイントは、仮想マシンがOSやCPUの違いを吸収してくれる点です。中間コードは「VMという共通の土台」の上で動くため、その下のOSが何であっても気にせず実行できます。

🌍
利点(可搬性)

中間コード1つで全部動くWinMacLinux

中間コード方式の最大の利点は可搬性(ポータビリティ)、つまり同じプログラムを環境を選ばず動かせることです。これを表す有名な標語が Write Once, Run Anywhere(一度書けば、どこでも動く)です。

もし機械語に直接コンパイルしていたら、CPUの種類ごとに別々の実行ファイルを用意しなければなりません。中間コードなら違います。
1度だけコンパイル:中間コードは1種類作ればよい
各環境のVMに任せる:Windows用VM・macOS用VM・Linux用VMがそれぞれ実行する
移植の手間が減る:環境ごとにソースを書き直さなくてよい

海外旅行で各国の電源プラグに合わせて機器を買い替える代わりに、万能変換アダプタ(=仮想マシン)を1つ持っていくイメージです。中身(中間コード)はそのままで、アダプタが現地の事情に合わせてくれるので、どこでも使えます。

🔍
なぜCPUごとに命令が違うのか

ソースコード変換x86 機械語ARM 機械語RISC-V 機械語

CPU(=計算を行う部品)は、メーカーや設計によって理解できる命令の種類が異なります。たとえばパソコンによく使われる x86 という設計と、スマートフォンに多い ARM という設計では、同じ「足し算をしろ」という命令でも、数字の並べ方や命令コードが違います。

これが中間コードを生み出した根本的な理由です。
機械語直接変換の問題:1つのプログラムを各CPUに合わせて別々に変換・テスト・配布しなければならない
中間コードの解決策:変換は1回だけ。各CPU向けのVMが「中間コードを自分の機械語に読み替える」役割を担う
VMがコストを肩代わり:プログラムの作者ではなく、VMの開発者がCPUごとの対応をすることで全員が楽になる

たとえるなら、世界中のホテルが「全室に変換アダプタを備え付ける」ようにしたおかげで、旅行者(プログラム作者)が自分でアダプタを持参しなくてよくなった、というイメージです。各ホテル(VM)が自分の電源規格に合わせて対応しているのでどこでも同じ機器が使えます。

可搬性と速度のトレードオフ

機械語(直接)速い 可搬性 ✕中間コード+VMやや遅い 可搬性 ○JITで差を縮めることができる

中間コード方式には可搬性という大きな利点がある一方、VMが間に入る分だけ実行速度がやや遅くなるという側面もあります。VMが中間コードを読んでから実際のCPU命令に変換するステップが余分にかかるためです。

なぜ今も広く使われているのか。この速度の差を大幅に縮めたのがJITコンパイラ(=実行しながら機械語に変換する仕組み)です。よく使う部分だけを機械語に変えてしまえば、その後は速く動くため、実用上の差はほとんどなくなります。
可搬性が必要な場面:ブラウザ上のJavaScript・Javaアプリなど、環境が多様な場面では中間コード方式が選ばれる
速度を最優先する場面:組み込み機器(家電などに入るコンピュータ)やゲームなどでは、機械語に直接コンパイルする方式が選ばれることも多い

どちらが「正解」ではなく、目的に応じて使い分けるものです。「移植しやすさ」と「実行の速さ」のバランスを意識して選択されています。

練習問題

🎯
基本情報技術者 練習問題

Q1.中間コード(バイトコード)の説明として最も適切なものはどれか。
A.人が読むためのソースコードそのもの
B.ソースコードと機械語の中間に位置する、仮想マシン向けの中間表現
C.特定のCPUだけが直接実行できる機械語
D.実行ファイルを主記憶へ読み込むプログラム
Q2.中間コードを実際に解釈・実行するものはどれか。
A.コンパイラ
B.リンカ
C.仮想マシン(VM)
D.テキストエディタ
Q3.中間コード方式の主な利点として正しいものはどれか。
A.OSやCPUの種類ごとにソースコードを書き直す必要がある
B.1度コンパイルした中間コードを、各環境のVMさえあれば動かせる(可搬性が高い)
C.必ず機械語より高速に動作する
D.ソースコードが不要になる

関連コンテンツ