JDKのインストール(Windows)と Java 関連用語の説明
今回は Java の開発キットである JDK(Java Development Kit) の Windows へのインストール方法についての紹介です。
ただ Java は JDK, JRE, Java SE など略称がいっぱいです。これらのJava に関連する用語についても説明しています。
Java は用語がいっぱいあり、何をインストールするのか、何がインストールされたのか、 よくわからないといったことがありました。 そこで、それらの用語について私なりにまとめたものをインストール方法と一緒に紹介したいと思います。
Java アプリケーションの実行の仕組み
Java アプリの実行の仕組みから先に説明します。まず、 比較として通常(Native)のアプリケーションでの実行の説明から行きましょう。
Native では gcc, VC++ といったコンパイラーで人間が書いたソースファイルを機械が読みやすいマシン語(機械語) に変換した実行ファイルを作成します。 このファイルは 0, 1 で書かれたバイナリーで、これを OS が読み取って実行します。

一方、 Java ではソースファイルをコンパイルするとバイトコードと呼ばれるファイルが作成されます。これはソースコードと機械語との中間言語のファイルです。
これを Java の仮想マシン JVM(Java Virtual Machne) が読み取り、実行します。

この JVM の環境を提供するのが、 JRE(Java Runtime Environment) というソフトウェアのセットです。
この中の java.exe にバイトコードを渡して、実行します。
このため、Java 製アプリを実行するには JRE が必要です。 通常 Java のインストールというとこちらを指します。
Java アプリ作成に必要なソフトウェアのセットが JDK (Java Development Kit)で、 Java の SDK といったところです。
JDK の中の Java コンパイラー(javac.exe) を使って、 ソースファイル(*.java) からバイトコード(*.class)を作成します。 Java の配布パッケージとしてよくある jar ファイルは class ファイルを単に zip で固めたファイルです。
なお、 JDK をインストールすると JRE も一緒にインストールされます。
ただし、こちらはプライベート JREといって、 JDK 用のフォルダー内にインストールされます。 このため、通常使っている JRE に影響を与えることなく、別バージョンの JRE 用のアプリを開発する ということもできるらしいです。
なんでこんな仮想マシンという仕組みをとっているかというと、もちろんメリットがあってやっています。 ただ、その説明はインストールの解説の後に行うことにします。
JDK のダウンロード
Java プラットホーム
Java の開発環境をインストールしていくわけですが、 ここでまた、Java にはいくつかの開発環境(Java プラットホーム)があります。 Java プラットホームをまとめると次のような感じです。 JDK はこのうちの標準版である Java SE の開発キットです。略称 | 名称 | 説明 |
---|---|---|
Java SE | Java Platform, Standard Edition | 標準版。主なターゲットはデスクトップ(PC)。 |
Java EE | Java Platform, Enterprise Edition | 企業向け。主なターゲットはサーバーサイド。 |
Java ME | Java Platform, Micro Edition | 組み込みシステム、モバイル用。 |
JDK の選択
いよいよ JDK のダウンロードです。以下の Java SE のダウンロードページから行います。

3 種類のダウンロードリンクがありますが、 "JDK" または "NetBeans 付きの JDK" を選択します。
NetBeans は Visual Studio に当たる IDE です。 IDE も一緒に入れたければ、 JDK + NetBeans を選択して下さい。
Java の IDE では NetBeans 以外にも Eclipse や IntelliJ IDEA あたりが有名どころです。 というよりもシェアとしては Eclipse が圧倒的人気で、 2 番目が IntelliJ です。
追記 2013-10-02
画像では 3 種類になっていますが、 次節で説明する JavaFX が JDK と一緒にインストールされることになったので、 現在は 2 種類です。JavaFX
もう一個残った JavaFX についても説明しておきます。分かれていますが、今のバージョン(7u21)では JDK と一緒に JavaFX もインストールされるみたいです。
JavaFX というのは Rich Internet Application (RIA) の GUI ツールキット(API)です。
といっても、"それ何?" という人も多いと思います。 RIA は Adobe Flash や Microsoft の SilverLight といった類のものです。 ブラウザーにプラグインとしてインストールし、 よりリッチなコンテンツや Web アプリを提供するための技術です。
Web のクライアント側スクリプトとしては JavaScript で統一されてしまった感がありますが、 Java もデビュー時は クライアントサイドの言語でした。その Java で作ったものが Java アプレット です。
JavaFX は次世代の Java アプレットに当たります。
ちなみに JavaFX は 1.0 として出た頃はスクリプト言語でした。 しかし、 Sun が Oracle に買収されたあたりで方針転換し、 2.0 から今の API の形態になっています。
また、方針変換に伴い JavaFX はブラウザー上だけでなく、デスクトップアプリの GUI ツールキットとしても使えるようになりました。 Java では AWT, Swing, SWT といった GUI ツールキットがありますが、 その最新版とも言えます。
Windows(.NET) では WPF と SilverLight に分かれていますが、それが合わさった感じです。
JDK インストーラー
前節 で "JDK のみ" を選択したとして進めたいと思います。 "NetBeans 付き" でもほとんどやり方は同じです。JDK のみを選択するとプラットホーム(OS)別のインストーラーのダウンロードページとなります。

ここで、ライセンス条項に同意して、 インストーラーをダウンロードします。
32 ビット PC であれば jdk-XXX-windows-i586.exe、 64 ビット PC なら jdk-XXX-windows-x86.exe です。
このページでは、その他にもデモやサンプルのファイルがおいてあります。 お好みでダウンロードして下さい。
JDK のインストール
インストールはダウンロードしたインストーラーを実行します。
ここで、インストール先を変更していた方がお勧めです。
デフォルトでは "C:\Program Files" 以下なのですが、 たまにパスにスペースを含む場合に正常に動作しないプログラムがあるためです。 また、 "C:\Program" というフォルダーを作るのは問題があり、後で変えるように言われるので、 そちらもやめておきましょう。
その後はウィザード従えば、インストールされます。
オプションで [公開用の JRE] を外していなければ、 そのまま JRE のインストールが続けられます。 こちらは開発時に使う プライベート JRE ではなく、普段使う JRE です。 こちらのパスは変えなくても大丈夫だと思いますが、気になる人は変えておきましょう。
この状態で、 javac (コンパイラー)などをフルパスで指定すれば、実行できるのですが、 環境変数 PATH に実行ファイルのある bin フォルダーを追加していた方が使いやすくなります。
また、ツールや JVM 言語の中には次で説明する JAVA_HOME を設定しておく必要があるものも多いです。
環境変数の設定画面の呼び出しは Windows のバージョンによって違うのですが、 基本的に [(マイ)コンピューター] を右クリックして [プロパティ] を選択し、 [詳細設定] を選ぶと出てくると思います。
単に bin フォルダーを PATH に追加するのではなく、 JAVA_HOME の変数を介して追加します。
環境変数 | 値 |
---|---|
JAVA_HOME | インストール先のフォルダー(C:\Programs\Java\jdk1.7.0_21 など) |
PATH (追加) | %JAVA_HOME%\bin |
新しいバージョンをインストールした場合、 環境変数を設定し直す必要があります。 前の PATH の記述を消すのは面倒ですが、 このように設定しておけば、 JAVA_HOME の値を変更するだけでよくなります。
以上でインストールの説明は終わりです。
これ以降は、 JVM の仕組みについて気になった人のために、もう少し JVM のメリット、デメリットについて説明をしておきます。
仮想マシン(JVM) のメリット、デメリット
コンパイル型と比べたメリット
メリットとしては次のようなものが考えられます。- クロスプラットフォーム
- 構文解析と最適化処理の分離
- クロスランゲージ
クロスプラットホーム :
もともと
Write once, run anywhere(一回書けば、どこでも動く) がスローガンでしたし、 これは売りなのでしょう。
ただ、 C++ でも Qt といったクロスプラットホームのフレームワークを使えば、 同じようなことはできます。
もちろん、 Qt ではプラットホーム別の処理を書く必要が全くないということは ありません。しかし、それは Java も同様です。
また、バイトコード等の仕様は公開されているので、 JVM を独自につくることができます。
新しく OS などの環境をつくったとして、そこで JVM さえ作れば、 すでにたくさんある Java のアプリがそのまま動くようになります。
実際には、そのまま動くほど、おいしい話ではありませんが、 速度向上の目的のものを含めると多くの JVM が開発されています。
構文解析と最適化処理の分離 :
コンパイラーの仕事のうち、大きなポイントが 2 つあります。
一つが言語の仕様に基づき、ソースを解釈する処理です。 この言語の仕様を決めるところが言語作成者の腕の見せ所であり、 センスを問われる部分でしょう。
もう一つはプログラムをいかに速く動かすかという最適化の部分です。 こういうところに情熱を燃やす人もいます。
この特性の違う二つをコンパイラーと JVM で分けて開発できるようになります。
クロスランゲージ :
前述の分離により、 中間言語へと変換するコンパイラーさえ作れば、 新しい言語でも最適化の恩恵を受けることができます。
また、一旦中間言語に直すので、違う言語間でのやり取りが簡単にできるようになります。
本来、 JVM は Java 用ですが、これらのメリットにより、 Scala 、 Groovy を始めとした 200 を超える新しい言語が生まれています。 これらの JVM 上で動作する言語を JVM 言語 と言います。
この多くの JVM 言語を生み出す環境を用意したことが、 Java の一番の功績ではないかと個人的には思います。
コンパイル型(Native)と比べたデメリット
逆にデメリットもあります。- 重い、メモリー消費量が多い
- リバース エンジニアリングされやすい
- システムへの JRE のインストールが必要
C, C++ といった言語では事前にコンパイルします。 それに対して Java では、 実行時にコンパイルします。 これは JIT コンパイル(Just In Time) と呼ばれています。
実行の際にコンパイルするので、その時間がかかりますし、 コンパイル結果のマシンコードをメモリー上に確保するので、メモリーを大量に消費します。
このため、初期の Java は「使い物にならない」といわれるほど、 遅いものでした。 実を言うと、私は Java が嫌いなのですが、 この第一印象の悪さが一因となっています。
しかし、 よく使うところだけコンパイルするなどの技術が盛り込まれ、大分改善されています。
最近では条件によっては事前コンパイルよりも高速になることもあるそうです。 ただ、そうはいっても基本的には遅いし、メモリーも使います。
リバース エンジニアリングされやすい :
これは商用アプリに限った問題です。
実行ファイルから元のソースコードの情報を得ることをリバース エンジニアリングと呼びます。 これは Java に限った技術ではありませんが、中間言語の形式でリリースする Java では特にやりやすくなってしまいます。
これを防ぐための難読化という技術もあります。
JavaScript の難読化 は速度を上げるために空白等を取り除いて、結果読みにくくなるものですが、 Java の難読化はわざとソースコードを読みにくくします。 しかし、これには新たな不具合が生じたり、速度が低下したりといった危険性があります。
最近のアプリでは減ってきていますが、アルゴリズムで勝負しているような部分は、 C, C++ といった Native な言語で実装する必要があります。
システムへの JRE のインストールが必要 :
インタープリター型と比べたコンパイル型のメリットとして、 "コンパイルした実行ファイルだけで動作する"というものがあります。
しかし、 Java のアプリは JVM(JRE)が必要で、そのメリットがありません。
インタープリター型(スクリプト)との違い
仮想マシンを使う仕組みはインタープリター型の言語とよく似ています。しかし、人が書いたコードを事前にマシンが読みやすい中間言語にコンパイルしているため、 その分、速度の向上が望めます。
コンパイル型との比較で挙げた JIT コンパイルなどの技術などもあり、 Java のアプリは大抵のスクリプト言語よりも 5 倍程度、速いらしいです。
ただ、 Ruby は Ver. 1.9 から RubyVM を内蔵していますし、 Python の PyPy や JavaScript の V8 エンジンなどは JIT コンパイルの技術が使わており、 速度の点に関しては、スクリプト系も向上していっています。
追記 - 2013-05-13
DartVM にいたっては JVM の速度を超えたらしいです。また、コンパイルが不要ということは、 手軽というインタープリター型のメリットとも言えます。
まとめ
最後に仮想マシンのシステムについてまとめてみます。速度に関しては、条件にもよりますが、概ね次のような関係となっています。
インタープリター型 < 仮想マシン < コンパイル型
また、 コンパイル型の"実行ファイルだけで動作する点"やインタープリター型の"コンパイルが不要な点" と両方の利点をともに失っています。
こうまとめるとあまり良い点はないように見えます。
しかし、 Micorsoft も Java と同じような .NET CLR のシステムを採用しました。 それだけ、 構文解析と最適化の分離やクロスランゲージといったメリットが大きいということでしょう。
ただ、これは開発サイドのメリットで、純粋にユーザーの視点からはコンパイル型が一番です。 しかし、速い技術進歩を求められるソフトウェア開発では必要な技術だと思います。
例えば、プログラミング言語が成熟するまで 10 年以上必要だと言われてきましたが、 Java や .NET を使えば、できてすぐ、高機能の最適化や豊富なライブラリーが使えるようになります。 また、既存のアプリに部分的に適用していくといったことも可能です。
Scala のインストール(Windows)と Emacs モードの設定
Scala はオブジェクト指向と関数型プログラミングのマルチパラダイムの言語であり、 JVM(Java 仮想マシン)上で動作する JVM 言語です。
今回はこの Scala の Windows へのインストールと簡単な使用法、および Emacs の scala 用モードの設定についての記事です。

最近、 Scala を始め、 Haskell, F#, Erlang, Clojure といった関数型プログラミング言語が注目を集めています。 Java は古いはいいとしても、 関数型でオブジェクト指向が古くなるということないでしょう。 しかし、適材適所で使えばかなり有用そうですし、 新しいパラダイムを覚えることはプログラミング力の向上にもなります。
何か 1 つちゃんと身につけたいなと思うのですが、どれがいいかは悩みます。 そこで、主要なものは試してみようということで、第一弾を Scala にしました。
『7つの言語 7つの世界』 に出ていたという理由もあります。
![]() | 7つの言語 7つの世界 (2011/07/23) Bruce A. Tate 商品詳細を見る |
その試した際のインストール方法などをまとめて記事にしてみました。
Scala とは
関数プログラミング言語の中でも Scala の特徴はマルチパラダイムと JVM 言語です。マルチパラダイム :
C++ はオブジェクト指向言語ですが、 C と同じ手続き型で記述することができます。 このパラダイムのつなぎとなれるというのは大きなメリットでしょう。
Scala は大枠はオブジェクト指向の言語ですが、関数型プログラミングが可能な能力を持っています。
JVM 言語:
Java はソースコード(*.java)をコンパイルして、 バイトコードと呼ばれる中間言語のファイル(*.class)を作成します。それを JVM(java.exe) が実行します。
Scala も同様にコンパイルで、バイトコードを作成し、 JVM 上で動作します。(スクリプトとして動作させることもできます)
JVM 上で動作するので、 Java の豊富なライブラリーを使うことができます。 また、 逆に Scala で作成したクラスを Java から利用することもできます。

Scala の名前の由来は "SCAlable LAnguage" (移植性、拡張性のある言語) であり、 オブジェクト指向、 Java と関数型の連結の高さからきています。
また、 イタリア語で "階段、はしご" を意味しています。 Scala のマークは開発者であるマーティン・オーダスキー教授の職場にある螺旋階段が素になっているらしいです。
インストール
JDK のインストール
バイトコードを生成するのに Java 開発キット(JDK) を利用します。 このため、まず JDK をインストールする必要があります。簡単にいうと、以下の手順になります。
- インストーラーをダウンロード
- インストーラーを実行
- 環境変数を設定
環境変数 値 JAVA_HOME インストール先のフォルダー(C:\Program Files\Java\jdk1.7.0_21 など) PATH (追加) %JAVA_HOME%\bin
(JAVACMD で java.exe のフルパスを設定でも可)
Scala のインストール
ダウンロードページからインストーラー(scala-X.X.X.msi) または圧縮ファイル(scala-X.X.X.zip) をダウンロードします。
ちなみに、 [Scala tool support] の中身は gEdit と Emacs 用のモードです。 Emacs に関しては後述しますが、使用する場合でもここでダウンロードする必要はありません。
以降はインストーラーをダウンロードしたとして説明していきます。
圧縮ファイルの場合はインストール項目を選択できないのと、 手動で bin フォルダーを PATH に追加する必要がある点を除けば、中身は同じです。
まず、ダウンロードしたインストーラーを実行します。
実行し、進めていくと [Custom Setup] の画面になります。
ここで、必要であれば、 [Browse] でインストール先を変更します。

また、 インストール項目も選択出来ます。 といっても、 サンプルコードや Scala のソースを選択するぐらいですが。

後は、そのまま進めていけば、インストールは完了します。
ただし、 PATH に設定された値は "C:\Program Files\Java\scala\\bin" のように \ 記号が余分に追加されています。(Ver. 2.10.1)
大抵はこのままで問題無いのですが、 eshell のように対応していないものもあるので、修正しておいた方がいいでしょう。
IDE のプラグイン
Java の主要な IDE 用のプラグインが用意されていて、 IDE での開発もできるようになっています。Emacs 派の私としては IDE は使いませんが、リンクだけ紹介しておきます。
IDE | リンク |
---|---|
Eclipse | Scala IDE for Eclipse |
IntelliJ IDEA | JetBrains Plugin Repository :: Scala |
NetBeans | Scala - NetBeans Wiki |
なお、 IDE の中では、今のところ IntelliJ のプラグインが評判がいいみたいです。
また、 scala サイトのダウンロードページにあるのは、 gEdit と Emacs だけですが、 Vim 、 TextMate など様々なエディターのプラグインが作成されています。
使用方法
scala は 3 つの方法で使用することができます。- 対話モード (REPL)
- スクリプト
- コンパイル
なお、詳細は scala -help, scalac -help で確認してください。 (scalac のオプションはすべて scala で使用できます)
対話モード (REPL)
REPL と呼ばれるもので、 1 行づつ結果を確認することができるモードです。 動作確認などで使用します。scala(.bat) を引数なしで実行すると対話モードとなります。
終了する場合は :quit と入力します。

Perl や Ruby のように -e オプションで式の文字列を渡して、 実行することも可能です。
スクリプト
scala(.bat) にソース(*.scala) を直接渡すとスクリプトとして動作します。次節のコンパイルではエントリーポイントを定義する必要がありますが、 スクリプトの場合はファイルを上から順に実行します。
hello.scala :
println("Hello, World!") println("Hello, Japan!") println("Hello, Tokyo!")実行結果 :
~/seven/scala $ scala hello.scala
Hello, World!
Hello, Japan!
Hello, Tokyo!
ただし、 Perl や Ruby の -c のような文法チェックだけのオプションは無いみたいです。
また、文法エラーのファイルを実行するとエラーが出ずに固まることも多いです。私としてはコンパイルの方がお勧めです。
コンパイル
コンパイルの場合は次の手順になります。- scalac(.bat) でコンパイルして、 class ファイルを作成
- scala(.bat) に class ファイル(拡張子は除く) を渡す
Java の場合は main という名前のクラスメソッド(static)がエントリーポイントとなります。 Scala も同じですが、 クラスメソッドはシングルトンオブジェクトで作成します。
helloWorld.scala :
object HelloWorld { def main(args: Array[String]) { println("Hello, World!") // コマンド引数を表示 args.foreach(arg => println(arg)) } }コメントを含め、日本語を使用したい場合は BOM(シグネチャー)なしの UTF-8 で保存する必要があります。
実行結果 :
~/seven/scala/sample $ scalac helloWorld.scala ~/seven/scala/sample $ ls HelloWorld$$anonfun$main$1.class HelloWorld$.class HelloWorld.class helloWorld.scala ~/seven/scala/sample $ scala HelloWorld foo bar Hello, World! foo bar
実際のアプリでは、ソースファイルがひとつということはなく、 複数ファイルからなるプロジェクトということが多いでしょう。 このプロジェクトのビルドは sbt を使うのが、 Scala では一般的のようです。
ただ、こちらは本格的に使うようになってからということにしたいと思います。
Emacs モードの設定
scala-mode の選択とインストール
[Options] -> [Manage Emacs Packages] メニュー等でパッケージのリストを開きます。 ここで、 scala 用のモードは 2 つ見つかります。- scala-mode
- scala-mode2
scala-mode2 は作者によると scala-mode に比べて、インデントやハイライトが賢くなっているらしいです。 インデントやハイライトを重視して、 scala-mode2 を使うことにします。
scala-mode の方も括弧の electric モードやスニペットの使用など魅力的な機能はあります。 ただ、部分的な機能であれば、本格的に使うようになった時、後から自分で移植するということもできるかもしれないので、 とりあえず気にしないことにします。
どれを使うか決めたら、後はパッケージを選択して、 install を実行すればいいだけなので、簡単です。
ENSIME のインストール
編集用のメジャーモードとは別に ENSIME(the ENhanced Scala Interaction Mode for Emacs) という拡張用の Lisp もあります。 こちらのインストール方法も紹介します。こちらはパッケージとして登録されていないようなので、ダウンロードページから取得します。 ダウンロードした圧縮ファイルを任意のフォルダーに展開します。 ここでは、 ~/elisp/ensime 以下に展開したとします。
(インストールフォルダー)/elisp を load-path に追加する設定と scala ファイルを開いた時に一緒に起動する設定を ~/.emacs.d/init.el に記述します。
(add-to-list 'load-path "~/elisp/ensime/elisp") (autoload 'ensime-scala-mode-hook "ensime" "Conveniance hook function that just starts ensime-mode." t) (add-hook 'scala-mode-hook 'ensime-scala-mode-hook)ENSIME のサイト等での説明では
require
で記述されていますが、
起動時に常にロードするのは嫌だったので、 autoload
に変えています。また、 hook に hook をかけているのが、おかしく感じるかもしれません。 名前が紛らわしですが
ensime-scala-mode-hook
は実際にはホックではなく、 モード呼び出し用の関数です。
ENSIME は主な機能はプロジェクト開発用みたいなので、まだちゃんと使っていません。 使用方法などは他のサイトなどを参考にしてください。
雑把の仮想マシン(JVM, .NET, BEAM, スクリプト言語, LLVM)
今回は JVM, .NET といった仮想マシン(VM)についての記事です。
最初、 .NET と仮想マシンの説明のスライドを作っていたのですが、
最近 JVM と BEAM を少し調べて興味がでてきたので、合わせて VM の話としました。
そうすると今度は、スクリプト言語や LLVM の話も外せないなと思って足したら、結構な大作になってしまいました。
スライド版です。
ここからブログ版です。
はじめに
仮想マシンといっても、 OS のエミュレーターのようなものではなく、 JVM といったプロセス仮想マシンについてのお話です。JVM 、 .NET Framework など最近、この仮想マシン(VM)のシェアが大幅に増加して来ました。
また、 LLVM(正確には VM ではない)の登場や VM を利用したスクリプト言語の高速化など 今 仮想マシンが熱い です。
そこで、 "VM とは何か ?"、"なぜ使うのか ?" といったことについてざっくり説明していきます。
目次
- 仮想マシンとは
- コンパイラー、インタープリター型との比較
- 特徴
- メリット、デメリット
- 各種VM について
- JVM、.NET Framework、Erlang VM (BEAM)、スクリプト言語での VM、LLVM
仮想マシンとは
コンパイラー、インタープリター型と比較にして VM の概要を説明します。通常(Native)アプリ
C, C++ に代表される Native やコンパイル型と呼ばれるタイプのアプリケーションは次のような手順で、作成、動作します。- ソースファイルを用意
- コンパイルして実行ファイルを生成
- コンピューター(OS)上で動作

ソースファイルは人が読み書きするテキストファイルです。
これをコンパイルして OS(機械) が読める マシン語(機械語) に変換します。
マシン語のファイルは機械が読むものなので、 0, 1 の並びです。 これはバイナリーファイルと呼ばれます。(厳密にはテキストファイルも 0 1 の並びですが)
インタープリター型
スクリプト言語、インタープリターと呼ばれるタイプは、コンパイルを必要としません。 インタープリターに直接ソースファイルを渡して、実行することができます。
これらの代表としては Perl, Ruby, Python といったところでしょう。 JavaScript も実行するのが OS ではなく、ブラウザーですが、スクリプト言語です。
インタープリター型はコンパイルが不要という手軽さが利点ですが、 その代わりコンパイル型と比べて、実行速度が遅いという欠点があります。
仮想マシン
C#, Java などの言語が使っている仮想マシン(VM)は OS(マシン) 上に仮想的な OS(マシン) を用意します。 VM 自体は、基本的に Native アプリケーションで、 OS が実行します。Native では実行ファイルはマシン語で書かれたファイルですが、 VM の場合は中間コード(バイトコード)です。 これはソースのプログラミング言語とマシン語の中間であり、 Native と同様にソースファイルをコンパイルして作成します。

VM を実現しているアプリケーションやライブラリーの集まりをランタイム (Run-time emvironment, 実行環境) と呼ぶことが多いです。
インタープリターと VM の違い
インタープリターと VM は似ていて、インタープリターを VM と呼ぶことさえあります。 この 2 つの違いを見ていきましょう。インタープリターはたいてい次のような手順で実行します。
- ソースファイルを解析
- 字句解析、構文解析を行います。ここではまとめてソース解析と呼んでいます。
- 構文木を作成
-
構文解析により、ソースコードの内容をインタープリターが扱いやすい構文木と呼ばれるデータ構造にします。
- 構文木を評価エンジンが解釈、実行
- 解釈、実行することを評価(evaluate)といいます。
また、この評価する部分がインタープリターの中心で、 評価エンジンの部分をインタープリターと呼ぶこともあります。
- 解釈、実行することを評価(evaluate)といいます。

このインタープリターと VM の大きな違いは次の 2 つです。
- 中間コードなので、ソース解析が不要
- JIT(Just In Time, 実行時) コンパイル
インタープリターが実行時にソース解析を行うのに対して、 VM では事前にコンパイルして、 ソース解析を済ましておきます。 実行時にソース解析が不要になる分だけ、速度的にお得です。
この中間コードはソースコードのように人が読める必要がないため、たいていバイナリーであり、 バイトコード と呼ばれます。
中間コードといっても、マシン語ではないので、 VM が解釈、実行します。 そこで、 JIT コンパイルを使います。これが 2 つ目の違いです。
実行時 (JIT) コンパイル
VM は中間ファイルの実行時にマシン語にコンパイルしてから実行します。VM が必ず JIT コンパイルを使うというわけでもなく、インタープリターのように実行することもあるのですが、 たいていは JIT コンパイルが使われています。

この方法は Native のコンパイルと比べて、制約、デメリットがあります。
- コンパイル時間も実行時間に含まれるため、最適化に時間をかけれない
- 生成したマシン語コードはメモリー上に保持するので、メモリーを大量に使用する
とはいっても、 Native のコンパイラー型よりは遅いです。 特に起動時に行うコンパイルが多いため、起動には時間がかかります。
インタープリター << VM < コンパイラー
しかし、 JIT コンパイルも改良され、あくまで部分的にですが、 Native よりも早くなることもあります。
よく使うところだけコンパイルすることによって、 コンパイル時間を減らし、 メモリー消費量の削減をします。
- 起動時にはインタープリター形式で実行し、プロファイルを取る
- よく使う部分(メソッド)、フローだけコンパイル
(コンパイルしてない部分はインタープリター形式)
例えば、正常系、異常系の if 分岐があったとして、正常系だけコンパイルするといった感じです。
実行時の環境がわかっていることによって、より状況に合わせた最適化ができます。
スクリプト言語では JIT コンパイルを使わないのか?
インタープリター形式よりもマシン語に直す JIT コンパイルの方が高速です。VM の特徴として、 JIT コンパイルをあげましたが、
"速いのだったら、スクリプト言語でも JIT を使えばいいじゃん"
と思われる人もいると思います。
確かにその通りなのですが、 スクリプト言語の場合にはコンパイルに関して難しい問題があります。
それはスクリプト言語の多くが動的型を使っている点です。
Java, C# は変数宣言で型を指定する静的型ですが、 動的な型では変数の型を特定しません。
この柔軟性はスクリプト言語の書きやすさにもなっています。 ただその分、高速なコンパイル済みコードの生成を難しくしており、 コンパイルするメリットがなくなります。
そのため、前はスクリプト言語は JIT コンパイルはしないものだったのですが、 最近は状況が変わってきました。
用語の区別
スクリプト言語で使われる VM, JIT コンパイルについては後述しますが、ここでは今後、次のように用語を区別します。用語 | 説明 |
---|---|
インタープリター | 直接、ソースファイルを実行。 マシン語にはしない。 |
JIT コンパイル | 実行時にマシン語にしてから実行 |
VM | 中間コードを実行 JIT コンパイルしないものもある。 |
スクリプト | 直接、ソースファイルを実行。 JIT コンパイルするものも出てきた。 |
仮想マシンの特徴
VM のメリット、デメリットデメリット
最初にデメリットからあげます。- 遅い、メモリー消費量が多い
- 速くなったとはいっても、 Native と比べれば、やっぱり遅いし、メモリーを大量に使用します。
- リバース エンジニアリングされやすい
-
商用アプリに限った問題ですが、中間言語の形式でリリースすることで、
元のソースを得るリバースエンジニアリングがやりやすくなってしまいます。
これを防ぐ難読化という技術もあります。これはわざとコードをぐちゃぐちゃにして、元をわかりにくくしています。 ただ、コードに手を加えるため、速度の低下や新たなバグを生成させる危険がある上、完全に防ぐものでもありません。 - インタープリター、 Native の両方の利点がない
- インタープリターはコンパイルがいらない手軽さがありますが、言語をインストールしないと使えません。
一方、 Native はコンパイルが必要ですが、生成ファイルだけで動作します。
VM はコンパイルが必要なうえに、実行環境(ランタイム)のインストールも必要となります。
メリット
デメリットが多い VM がなぜ広く使われているかというと、 当然、使うメリットがあるためです。- 移植性の向上
- 開発の効率化
- クロスランゲージ
移植性の向上
アプリケーションは中間コードの形式です。 そのため、 VM を OS 等の環境で変えれば、 アプリケーションはそのままで動作します。例えば、新しい OS を作ったとしても、 VM さえ用意すれば、大量のアプリがすぐ使えるようになります。
ただ、理屈はそうだというだけで、実際は環境ごとに手を入れて直さないと動かないということも結構あります。

開発の効率化
コンパイラーの仕事のうち、大きなポイントが 2 つあります。一つが言語の仕様に基づき、ソースを解釈する処理です。 もう一つはプログラムをいかに速く動かすかという最適化の部分です。
この特性の違う二つを VM では分けて開発できるようになります。

例えば、速度に関しては初期の Java は「使い物にならない」といわれるほど、遅いものでした。
しかし、中間言語、 VM の仕様が公開されており、多くの JVM が開発されました。 そこで、 前述の JIT コンパイルや世代別 GC といった高効率な GC(Garbage Collection) などの改良により、 かなり改善してきました。

また、ソース解析が分かれていることによって、新しい言語でも解析部分の作成だけで済みます。
例えば、 F# では次のような感じです。
- 関数型言語が流行っている
- 実行環境はそのまま使える
- センスを問われる言語仕様は実績のある OCaml を使う
- F# の出来上がり !

クロスランゲージ
中間コードを利用することによって、言語間のやり取りが簡単にできるようになります。共通したライブラリーが使える
- ライブラリーも中間コードなので、 1 つ作ればどの言語からでも使える
- スクリプト言語からのライブラリーの呼び出しも簡単

スクリプト言語の組み込みが簡単
- 全体を書きやすいスクリプトで作って、スピードネックだけ静的型言語で作ることができる(にかわ言語)。
- C++ など Native のライブラリーもラップして使えるようになるものが多い。
- 動的言語でアプリケーションに拡張性を持たせる(マクロ、プラグイン)

モジュールごとに言語を変える
私はアプリケーションの目的にあわせて言語を選択するものだと思っています。
それに加えて、今後はアプリケーションの部分(モジュール)の目的に合わせて言語を選択し、 組み合わせて、使っていくことになっていくのではないかと思います。
例えば、関数型言語は単体テストしやすい、並列処理に強いといった特徴があり、 アプリケーションのコア部分に向いています。 一方、 GUI はオブジェクト指向との相性がいいので、これらを組み合わせるといった感じです。

各種 VM
以降は VM 別に解説していきます。- JVM
- .NET Framework
- Erlang VM (BEAM)
- スクリプト言語での VM
- LLVM
Java 仮想マシン (Java Virtual Machine, JVM)
旧 Sun Microsystems 社が開発した Java 言語のための実行環境Write once, run anywhere
"一回書けば、どこでも動く" が Java のスローガンでした。スローガンからもわかるように Java が VM を使っているメインの目的はクロスプラットホームでしょう。
Windows, Linux といった PC の OS だけでなく、 厳密には JVM ではありませんが、その変種の Dalvik は Android といったモバイルの分野でも広く使われています。
ただし、 個人的には分離、仕様公開による副次的な方が功績が大きいと思います。
- ソース解析
-
Java の生み出した環境は素晴らしいものだと思いますが、
Java の言語仕様自体は単に C++ の仕様を劣化させただけのように私は感じます。
しかし、 Java を改良した言語や全く新しい言語など数多くの JVM 言語が生まれ、 それらを JVM の環境で動作させることができます。
- ランタイム(実行環境)
- 開発効率のところでも述べましたが、 Java はデビュー時は異常に遅いものでした。
しかし、仕様の公開などにより GC 、 JIT コンパイル性能が向上されていき JVM の機能の改良され、 それらの技術の促進にもつながっていると思います。
- 開発者が知っておくべき Java と仮想マシンの歴史 - @ IT
- Java はどのように動くのか - スライドでわかる JVM の仕組み
- Javaはどのように動くのか - 図解でわかるJVMの仕組み:連載|gihyo.jp … 技術評論社
JVM 言語
JVM はその名のとおり、もともと Java 用のものでしたが、 今では 200 を超える JVM 言語が生まれています。JRuby のように移植系の言語ではメジャーな汎用プログラミング言語はすべて移植されているのではないかという勢いですし、新しい言語にも興味深いものがたくさんあります。 動的型付け言語は JIT コンパイルによる高速化が難しいと説明しましたが、 JDK 7 からは動的言語のサポートも追加されています。 Java 専用だったものが、積極的に JVM 言語のサポートも行われているようです。 JVM 言語を大きく分けると次のような感じです。 ただ、実際はどっちでも動作するものが多いです。
JRuby はインタープリター、事前コンパイル、実行時(JIT)コンパイルと 3 つのパターンで動作できます。 また、 Clojure, Scala もスクリプトとして動作させることもできます。
- Clojure, Leiningen の Windows へのインストールと使い方 | プログラマーズ雑記帳
- Scala のインストール(Windows)と Emacs モードの設定 | プログラマーズ雑記帳
.NET Framework
Microsoft による開発、実行環境Common Language (共通言語)
.NET が登場した時には、 "MS が Linux に進出か ?" と思ったものです。実際、 mono(Xamarin) といった他のプラットホームで動作するものもありますが、 MS 自身は仕様の公開だけして、それほどクロスプラットホームには積極的ではないみたいです。
ちなみに他のプラットホームとしては .NET を JVM 上で動作させる IKVM.NET といった面白い試みもあります。 では、クロスプラットフォームが目的ではないとしたら、目的は何かというと、 私は Java では副次的効果であったクロスランゲージ(共通言語化)が最初からメインの目的だったと思います。
- ライブラリーを作ったら、 VC++, VB など複数の言語から使いたい
- これはユーザーの要望ですが、 MS 自身も多くの言語を抱え、言語ごとにライブラリーを用意するのは負担だと思います。
- 昔は COM 。
- 言語間を超えてオブジェクト(ライブラリー)を使う技術として COM がありました。
ただ、これが面倒で難しく、 かなり使いづらいものでした。
- 言語間を超えてオブジェクト(ライブラリー)を使う技術として COM がありました。
- .NET では共通(中間)言語化で垣根をなくし、言語間の連携が簡単に。
さらに .NET では新しい技術の導入にあたって、過去の資産も無駄にしませんでした。
COM は .NET でもそのまま使えますし、 昔の C++ ライブラリーも C++CLR(.NET 用の C++)でラップするだけで使えるようになっています。 VM ではコンパイル型、インタープリター型の両方のデメリットを持っていると書きましたが、 .NET に関しては OS 制作の強みで VM のデメリットも減っています。
- 動作にランタイムが必要
- OS と一緒にインストール
- コンパイル型は生成ファイルだけで動作可能
- コンパイルしたバイトコードを exe 形式に
用語
.NET では略称の用語がいろいろ出てくるので、それらについてまとめておきます。ちなみに Java の用語に関しては以前の記事をご覧下さい。 .NET の仕様は CLI として公開されています。
この CLI に従って MS が実装した実行環境(ランタイム)を CLR と呼びます。
ただ、これは実行のためのコアな部分だけです。 さらにライブラリーや開発ツール等を加えて .NET Framework となります。

略称 | 用語 | 説明 |
---|---|---|
CIL (MSIL) | 共通中間言語 Common Intermediate Language (MicroSoft Intermediate Language) | 中間言語 |
CLI | 共通言語基盤 Common Language Infrastructure | .NET の VM の標準化仕様 |
CLR | 共通言語ランタイム Common Language Runtime | CLI の MS による実装 |
DLR | 動的言語ランタイム Dynamic Language Runtime | CLR 上で動作する動的言語のためのライブラリー群 スクリプト言語を高速に動作させるためのサポート |
.NET | .NET Framework | 開発、実行環境 CLR にライブラリー、ツールなどを加えたもの |
.NET 言語
共通言語としていろいろな言語が使えるのですが、.NET の機能をフルに使うための 標準として C# を作成されました。C# は Delphi の作者として有名だった アンダース・ヘルスバーグさんが開発された言語で、 基本的に移植しかしない MS にしては開発に力を入れている言語だと思います。(Delphi 、 C#、 TypeScript も 0 から作ったかといわれると微妙ですが)。
言語作者として多くのファンを持つ人で、私も C#、 TypeScript あたりからファンです。
MS の旧言語も .NET に対応しています。
言語 | ベース言語 | 説明 |
---|---|---|
C++/CLR | VC++ | C# を使った方がいいけど、旧 C++ ライブラリーのラップで必要 |
Visual Basic .NET | Visual Basic | 動的言語の一部機能(DLR)を使用 |
J# | VJ++(Java) | |
JScript .NET | JScript(JavaScript) | コンパイルが必要 |
個人的には JScript は Windows におけるインストールいらずのスクリプト言語として重宝しているのですが、 コンパイルが必要となると C# の方がいいかなと思います。
ただ、 JavaScript への変換言語もありますし、それらと組み合わせると需要があるかもしれません。 WSH には VBScript という Visual Basic 風のスクリプトもあるのですが、 こちらはコンパイルすると VB.NET とかぶるためか、 VBScript.NET はありません。
また、旧言語からだけでなく、新しい言語、移植もあります。
言語 | ベース言語 | 説明 |
---|---|---|
F# | OCaml | 関数型言語 |
Windows PowerShell | シェル、シェルスクリプト | |
IronRuby | Ruby | 動的言語。 DLR 上に構築 |
IronPython | Python |
MicroSoft 製ばかりではなく、サードパティー製の言語も少しづつ出て来ました。
言語 | ベース言語 | 説明 |
---|---|---|
ClojureCLR | Clojure | JVM 言語の移植 |
Fantom | JVM、 .NET の両方で動く |
Erlang VM (BEAM)
大手通信メーカー Ericson の開発した Erlang 言語のための VM 。let-it-crash (クラッシュさせろ)
Erlang VM (BEAM) は JVM や .NET に比べると少しマイナーかも知れません。 Erlang の場合は今までと別の目的で VM を使用しています。Erlang は耐障害性の高いリアルタイム分散処理システムの作成を得意としており、 これを実現するための軽い特殊なプロセスの実現が目的です。
また、複数台のコンピューターに処理を分ける分散コンピューティングにも強くなっています。
ここでいう "耐障害性" は安定性とは別もので、むしろ逆の発想です。
エラーが発生してもプロセスを監視し、自動で復旧します。 エラーを起こさないのではなく、エラーを許容するシステム(fault-tolerant)です。

信頼性への最適化
Erlang は fault-tolerant に加え、実行時アップデートもでき、なるべくサービスを止めないシステムに向いています。サーバーサイドとしては、 今は Java が主流です。 JVM でも似たことはできますし、速さは JVM の方が上です。
- Twitter Storm : リアルタイム分散処理、 耐障害性
- vert.x : 実行時アップデート
速度は他の要素とトレードオフとなることが多いです。 例えば、 Ruby などは "書きやすさ" と "速度" の選択では書きやすさを優先し、 スクリプト言語として最高レベルの言語に仕上がっています。
Erlang も電話会社の言語らしく、速さよりも信頼性に最適化されています。 ライフラインのサーバーなどでは、信頼性を一番におくべきものだと思います。
- 2012-02-14 - トーフサロン
- マルチコア危機: Scala と Erlang の対立
- Javaはもう古い!次の主流は「関数型」 - [Erlang]分散システムに特化し耐障害性に優れた言語:ITpro
Erlang VM (BEAM) の言語
Erlang VM 上で動作する言語と言えば、もちろん、 Erlang です。 これは Prolog 風の関数型言語です。 ただし、この Prolog 風というのがクセモノで、かなり書きづらいです。 Erlang はその遅さと書きづらさにも定評があります。遅いのは信頼性の代償だとしても、書きづらいのはいただけません。
しかし、 最初 Java 専用の JVM から多くの JVM 言語が生まれたように、 Erlang VM でも Erlang 以外の言語がボチボチ登場しています。 書きやすさで言えば、中でも Elixir がお勧めです。
スクリプト言語での VM
ここからは動的言語でのコンパイルの問題について掘り下げた(ただし、さっくりと)後、 VM(JIT コンパイル) を利用しているスクリプト言語について見ていきます。スクリプト言語でも VM (JIT コンパイル)
インタープリター型よりも JIT コンパイルを使う VM の方が速いと記述しました。であれば、当然、 スクリプト言語でもインタープリターをやめて JIT コンパイルすればいいということになります。

動的型付けでの JIT コンパイル
ただし、ここで出てくるのが静的な型でないと高速なバイトコードにできないという問題です。この対処法はガードと呼ばれるもので、型を決めてコンパイルします。
- 決めていた型なら高速なバイトコード
- 違う場合は通常のインタープリター処理

変数のオブジェクトを自由に変えられるといっても、 普通書く時はめったに最初に入れた型から変えませんし、妥当な対処法だと思います。
ただし、最近コンパイル言語で使われている型推論のようなことは ちゃんとやるとかなり時間がかかります。 しかし、 int, string, ... というように単にガードを入れまくるのは、 逆に遅くなります。
そこで、実際は VM ごとに他にもいろいろやっているらしいです。 ただし、これ以上は踏み込まず、スクリプト言語別に移りたいと思います。 というよりは、あまりよく理解できていないので、踏み込めません。
- JIT - nothingcosmos wiki
- 流行りの JIT コンパイラは嫌いですか? — PyPy Advent Calendar 2011 v1.0 documentation
- FirefoxでJITコンパイルの「正しさ」を担保する”Invalidation” | ψ(プサイ)の興味関心空間
JavaScript V8 エンジン
Google の開発した JavaScript エンジンで、 Google Chrome で使用されています。 スクリプト言語にもかかわらず、 JIT コンパイルを使って高速な動作を実現させています。 また、オープンソースなので、サーバーサイドの Node.js などでも利用されています。 サーバーサイドも JavaScript で書くことによって、クライアントサイドとのソースの統一が実現出来ます。ただ、 V8 エンジンが有名ですが、 JavaScript エンジンの高速化は Chrome だけのものではありません。 Firefox では IonMonkey で JIT コンパイルを使っています。 Firefox では Asm.js にも対応しています。
これは 整数用の変数の場合、 + を付けて始めるなど特殊な書き方で型指定する JavaScript のサブセットです。 サブセットなので、 Asm.js に対応していなくても、 JavaScript として動作させることができます。
対応している場合には Native の速度が期待出来ます。
- asm.js:コンパイラのための低レベルかつ高度に最適化可能な JavaScript のサブセット - Publickey
- azakai: What asm.js is and what asm.js isn't
Dart VM
Dart は Google が JavaScript の置き換えとして開発している言語です。まだ開発中の言語ですが、着々と使われていっているようです。
- 続々出てきた JavaScript 系新言語。どれを使う? | プログラマーズ雑記帳
- Blossom が Dart に移行
- Google Dart:Polymer が Web UI を置き換える
- AngularJS の Dart へのポーティングが進行中
このような形態は Dart が最初ではなく、 実は Java もデビュー時はクライアントサイドの言語(Java アプレット)として開発されていました。

Dart VM は高速な V8 エンジンを改良して作成されており、速度にも期待が持てます。 実際、JVM を少し超えるレベルの速度らしいです。
- 最新の Dart VM が JVM に DeltaBlue ベンチマークで勝つ
- Frameworks Round 6 - TechEmpower Blog
- こちらのベンチマークはエラーが出ているせいか、まだ負けています。
Python(PyPy)
Python では JIT コンパイルを使った PyPy という処理系があり、 本家(CPython)よりも高速に動作するらしいです。- 流行りの JIT コンパイラは嫌いですか? — PyPy Advent Calendar 2011 v1.0 documentation
- ryu22eBlog:第八回ありえるえりあ勉強会 ~ PyPy のキホンの気 に参加しました #arielarea
ちょっとややこしいですが、先に RPython というサブセットを作って、 JIT コンパイルできるようにし、 それを使って Python と互換性の高い PyPy が作られています。
通常、 VM はバイトコードをトレーシングしますが、 PyPy の場合は RPython をトレースするので、メタトレーシング と呼ばれています。
この仕組みは PyPy の開発にかぎリません。 RPython を使って実装すれば、 他の処理系でも JIT コンパイルできるようになります。
実際に別言語の処理系として Ruby を RPython で実装した Topaz があります。 ただ、 次の RubyVM で述べるように Ruby 自体に VM が使われています。
まだ、 Topaz も開発中で、どうなるかはよくわかりませんが、 効果の程はどうかなと個人的には思っています。
また Topaz の現状はただの Ruby の別実装なので 新しい宝石名をつける程ではなったと思います。 Python 、 Ruby の両方のライブラリーを使えるような言語になると面白いのですが。
Ruby VM
Python と PyPy の関係と違い、 Ruby VM (YARV) はのバージョン 1.9 以降から本家(MatzRuby)に正式に採用されています。サイトの説明によると JIT コンパイルに関しては試験段階っぽいですが、それでも 5 倍程度高速らしいです。 本家以外ではそれぞれの VM で JIT コンパイルができます。
言語 | VM |
---|---|
JRuby | JVM |
IronRuby | .NET(DLR) |
MacRuby 、 Rubinus | LLVM (後述) |
LLMV
コンパイラー作成のための基盤。LLVM は略称ではなく、フルネーム
VM の話の中で紹介していますが、正確には LLVM は VM ではありません。 LLVM は Low Level Virtual Machine の略ではなく、これでフルネームです。おそらく誤解を生むので変えたのだと思いますが、今のサイトの説明ではそうなっています。 "VM でないのならば、なんなのか" というとコンパイラー基盤です。
ではコンパイラー基盤はというと、"コンパイラーを作るためのライブラリーやツールの集まり"です。 簡単にいえば、コンパラーを作るのを楽にするためのものです。
前の方で VM のメリットについていろいろ書いて来ましたが、これらは基本的に開発者目線のものです。
対してデメリットのほとんどは使用者側に生じます。 純粋に使用者側に立てば、 Native の方がメリットが多いでしょう。 そうはいっても、私も開発者であり VM のメリットは大きいと思っています。 LLVM は Native コンパイラーの作成に VM のメリットを持たせるものです。
VM と同じ利点
中間言語(LLVM IL) を使うことによって、 VM と同じ利点が得られます。
- 開発の効率化
- フロントエンド(ソース解析)だけ作ればいい
- 移植性の向上
- ただ、Windows はまだ試験段階で、Mac がメイン
(後述の Emscripten のように少しはあります)
VM じゃないといいつつ JIT コンパイルも
また、話が少しややこしくなりますが、 VM ではないと言いつつ、 JIT コンパイルもできますし、 GC もあり、 VM のように使えます。しかし、他の VM のようなランタイム(実行環境)を配布するような形態ではなく、 スクリプトへの組み込みとして限定したもので、若干オマケっぽい位置づけにあります。
これを利用した有名なものは Mac 用の Ruby である MacRuby です。 また Rubinus も LLVM を利用した Ruby です。
LLVM を使った言語
Clang :- C, C++, Objectiv-C 用コンパイラー
- コンパイルエラーのメッセージが親切らしい
- Apple 製
Objectiv-C 用コンパイラーの作成に Apple が LLVM を使ったことにより、 LLVM に Apple の後押しがついて、一気に有名になった感があります。
その他にも D 言語、 Scheme などの既存言語や Pure (関数型) などの新しい言語も出てきています。 その中でちょっと興味深いなと思ったのが Emscripten です。
これは LLVM のバイトコードから JavaScript を生成するツールです。 中間言語から変換するということは、LLVM を使ったいろんな言語から JavaScript に変換できることになります。
あと、ロゴがかっこいい
どうでもいいといえば、どうでもいいことなのですが、 LLVM はロゴがかっこいいです。ゲームやファンタジーが好きな人は知っていると思いますが、ワイバーン(飛行型の小型ドラゴン)です。 メタリックな感じで SF 心もくすぐられます。
まとめ
目的
今まで説明した対象の VM (LLVM の場合は中間コード) を使う主目的をまとめると次表のようになります。対象 | 主目的 |
---|---|
JVM | クロスプラットフォーム(移植性の向上) |
.NET | クロスランゲージ(共通言語) |
BEAM | 耐障害性、分散コンピューティング |
スクリプト言語 | 高速化 |
LLVM | コンパイラーの開発を効率化 |
クロスランゲージ
言語を組み合わせたアプリ開発を個人的には一番注目しています。クロスランゲージ関連でまとめたものが下表です。
VM | 言語 | ベース言語 | 動的言語 | C++ 連携 |
---|---|---|---|---|
JVM | 多 | Java | JSR 292 | JNI, JNA |
.NET | 中 | C# | DLR | COM, C++CLR |
BEAM | 少 | Erlang | Erlang が動的 | erl_nif |
使用出来る言語の量だけで言えば、 一番古くからある JVM が一番多いです。
シェアがあまり大きくない Erlang VM (BEAM) は少ないですが、 Elixir は魅力的な言語だと思います。
JVM には関数型言語も多くありますが、オブジェクト指向の Java がベースのため、 JVM は関数型言語には向いてない面があります。
例えば、 末尾再帰最適化(Tail Call Optimization 、 TCO) と呼ばれる機能は関数型では欲しい機能ですが、 JVM の制限により、 JVM の関数型言語では使えません。 .NET の場合は C# もオブジェクト指向ですが、機能はあります。もともと共通言語化が目的だからかもしれません。 BEAM はベースが関数型言語で使用可能です。
動的言語の高速化のためのサポートは .NET 、 JVM ともにあります。 BEAM は高速化に関してはよくわかりませんが、 Erlang 自体が動的型付けを使っています。
C++ ライブラリーといった旧資源の利用に関しては、 .NET が一番積極的な感じです。
ただし、 Java からも C++ の利用は可能です。 Erlang からも利用はできるようですが、 まだ試験段階らしいです。
- 末尾再帰最適化 - (hatena (diary ’Nobuhisa))
- JDK 7 の新機能: Java 仮想マシンにおける動的型付け言語のサポート
- Erlang の型記法( Type Notation ) - 檜山正幸のキマイラ飼育記
- JNI より簡単に Java と C/C++ をつなぐ「 JNA 」とは( 1/4 )- @ IT
- Integrating Erlang with C++ - Stack Overflow
今後は
その他の今後の動向が興味深いものについて、挙げてみます。- LLVM
- VM のシェアは増えてますが、やっぱり、 Native の利点は大きいでしょう。 Mac では LLVM が主流になると思います。他の環境ではどれだけ使われるようになるでしょうか。
- DartVM
- Dart はクライアントサイドとしても、もちろん注目ですが、 JVM の速度を超え、 サーバーサイドの言語としても注目です。
- スクリプト言語
- スクリプト言語における JIT コンパイルでの高速化は結構大変なので、 今やっているのは JavaScript 、 Ruby 、 Python といったメジャーな言語ぐらいです。 これからはもっと増えていくような気がします。
- Erlang VM (BEAM)
- サーバーサイドとして、 JVM vs BEAM では JVM に押されていますが、
今後シェアは増えていくのでしょうか ?
逆に耐障害性や分散コンピューティングといった BEAM の得意分野でも JVM が向上していき、減っていくのでしょうか ?