プロセス仮想マシン
JVM, .NET Framework
VMとも称される
比較
コンパイル型(C, C++ etc.)
コンパイラがソースファイルをコンパイルして実行ファイル(バイナリ)を生成する
コンピュータ(OS)上で動作する
インタプリタ型(Perl, Ruby, Python etc.)
インタプリタが直接ソースファイルを実行する
事前コンパイルなしで手軽だが実行速度は遅くなりがち
実行時のステップ
字句解析・構文解析といったソース解析を行う
構文木(AST)を作成
構文木を評価エンジンが解釈・実行
評価(evaluate)するともいう
評価エンジンのことをインタプリタと呼ぶこともある
仮想マシン型(C#, Java etc.)
コンパイラがソースファイルをコンパイルして中間コード(バイトコード)を生成する
バイナリだがマシン語ではないのでコンピュータが直接実行はできない
OS上で動作するVMがバイトコードを実行する
VMは基本的にNativeアプリケーション
実行時のステップ
ソース解析は事前に済んでいるので不要
JITコンパイル
メリット
移植性の向上
同じ中間コードが異なるOS・環境で動作する(理屈上は…)
開発の効率化
ソース解析と最適化を分けて開発できる
実際、Javaでは中間言語とVMの仕様が公開されることでJITコンパイルや世代別GCといった最適化手法が発展してきた
これらを考えるときにはソース解析はいったん考えなくても良い
ソース解析部分を実装するだけで新しい言語を作れる
F#は.NET環境で動く関数型プログラミング言語
実績のあるOCamlの言語仕様・文法を模倣しつつ.NET環境で実行可能にした
言うほどかんたんではないが
クロスランゲージ
ライブラリも中間コードになるので、一つ作れば同じVM上で動作する別言語でも使える
Javaで作ったclassファイルを JRuby, Clojureで利用するなど
文法は書きやすいスクリプト言語にして速度は仮想マシン型レベル
モジュールごとに言語選択ができる
GUIだけ関数型プログラミング言語、バックエンドはオブジェクト指向の言語、みたいな
デメリット
遅い、メモリ消費が多い
リバースエンジニアリングされやすい
中間言語から元のソースを得られる
難読化もできるっちゃできる
インタプリタ、ネイティブ両方のメリットがない
インタプリタとVMは似ている
JITコンパイル
VMは中間ファイルの実行時にマシン語にコンパイルしてから実行する
Native のコンパイルと比べて、制約、デメリットがある
コンパイル時間も実行時間に含まれるため、最適化に時間をかけれない
生成したマシン語コードはメモリ上に保持するので、メモリを大量に使用する
よく使うところだけコンパイルすることでメモリ消費量の削減をする最適化もある
トレーシング実行コンパイル
一回マシン語に直して実行したほうがインタプリタよりは早い
スクリプト言語とJIT
動的型付けを採用していることもあり、コンパイル済みコードの生成が難しく、コンパイルするメリットが薄くなる
JITコンパイルを採用していることもある
ガードと呼ばれる対処法
決めていた型なら高速なバイトコード
違う場合は通常のインタープリター処理
VMの種類
JVM
.NET Framework
Erlang VM
スクリプト言語のVM
V8
Dart VM
PyPy
Ruby VM (YARV)
1.9以降に採用されている
LLVM
VMではないが実質VM的なこともする
EVM
参考
http://yohshiy.blog.fc2.com/blog-entry-238.html