アプリケーション仮想化の過去と未来

アプリケーション仮想化の紹介

最近では、仮想マシン (VM) という言葉を聞くと、おそらく仮想化やハイパーバイザーを思い浮かべると思いますが、VM は比較的古い抽象化の概念の 1 つに過ぎません。抽象化とは、あるエンティティーから具体性を取り除いて一般的なエンティティーを作成する、よくある方法です。この記事では、最近の数ある新しいオープンソースの VM 技術のなかから、Dalvik (Android オペレーティング・システムの VM コア) と Parrot (動的言語を効率的に実行するためのオープンソース VM 技術) の 2 つについて詳しく探ります。

M. Tim Jones, Platform Architect, Intel

author photo - M. Tim JonesM. Tim Jones は組み込みソフトウェアのエンジニアであり、『Artificial Intelligence: A Systems Approach』、『GNU/Linux Application Programming』(現在、第 2 版です) や『AI Application Programming』(こちらも現在、第 2 版です)、それに『BSD Sockets Programming from a Multilanguage Perspective』などの著者でもあります。技術的な経歴は静止軌道衛星用のカーネル開発から、組み込みシステム・アーキテクチャーやネットワーク・プロトコル開発まで、広範にわたっています。彼は Intel に勤務していて、コロラド州ロングモン在住です。



2011年 7月 08日

Tim とつながるには

Tim は developerWorks で人気の高いお馴染みの著者の 1 人です。Tim が書いたすべての developerWorks 記事を閲覧してみてください。また、My developerWorks では、Tim のプロフィールを調べることや、彼やその他の著者、そして他の読者とつながることができます。

プラットフォーム仮想化とアプリケーション仮想化の違い

最初の仮想マシン (VM) は IBM によって 60 年前に、大規模で高価なメインフレーム・システムを共有するための手段として作成されました。その概念は現在の IBM システムにも引き継がれていますが、VM の一般的な概念は、今やその適用範囲を仮想化以外の多数の分野に広げるまでになっています。

仮想マシンの起源

VM の完全仮想化を初めてサポートしたオペレーティング・システムは、CMS (Conversational Monitor System) です。CMS は、完全仮想化と準仮想化の両方をサポートしていました。1970年代の初め、IBM は VM 制御プログラム (VM Control Program: VMCP) を実行している環境で、複数のシングル・ユーザー・オペレーティング・システムを実行する VM ファミリーのシステムを発表しました。それが、初期の Type-1 ハイパーバイザーです。

IBM が 1960年代に広めた仮想化のタイプは、プラットフォーム (あるいはシステム) 仮想化して知られています。この形の仮想化ではハードウェア・プラットフォームが仮想化され、このプラットフォームがさまざまなオペレーティング・システムおよびユーザーによって共有されるようになっています。

VM のもう 1 つのタイプは、マシンに依存しない性質を提供するためのものです。アプリケーション (またはプロセス) 仮想化と呼ばれるこの形の仮想化では、アプリケーションがその物理環境に依存しないように、(アプリケーションにとって) 抽象化された環境を作り出します。


アプリケーション仮想化の特徴

アプリケーション仮想化空間では、VM を使用することによって、ハードウェアに依存しないアプリケーションの実行環境を提供します。その一例として、図 1 を見てください。図の一番上にあるのは、開発者がアプリケーションを作成するために使用する高級言語です。この高級言語のコードが、コンパイル・プロセスによってオブジェクト・コードと呼ばれる中間表現にコンパイルされます。仮想化されていない環境では、この (マシンに依存しない) オブジェクト・コードがネイティブ・マシン・コードにコンパイルされて物理プラットフォーム上で実行されますが、アプリケーション仮想化環境の場合、オブジェクト・コードは抽象化マシン内部で解釈されてから実行されます。この場合の重要な利点は、抽象化マシン (インタープリター) をサポートするハードウェア・プラットフォームであれば、どのプラットフォームでも同じオブジェクト・コードを実行できることです。

図 1. プラットフォームに依存しないアプリケーション仮想化の VM
プラットフォームに依存しないアプリケーション仮想化の VM を示す図

移植可能なオブジェクト・コードの実行環境を作り出すだけでなく、アプリケーション仮想化はホスト上で実行されている他のアプリケーションから VM を切り離すための環境も提供します。このようなセットアップには、例えばリソース管理やセキュリティーを細分化するなど、いくつもの利点があります。

VM のオブジェクト・コードはバイト・コードとも呼ばれ、インタープリターが実行する命令セットを具体的に定義します。バイト・コードという用語は、単純さとパフォーマンスを目的に、仮想命令セットをシングル・バイトのセットとして効率良く実装したことから生まれた用語です。

ここからは、アプリケーション仮想化の仮想マシンの過去の使用例を紹介し、最近のアプリケーションをいくつか取り上げて検討します。


アプリケーション仮想化の歴史

アプリケーション仮想化が初めて適用されたのは、1960年代のことです。その 1 つに、BCPL (Basic Combined Programming Language) があります。ケンブリッジ大学の Martin Richards 氏が開発したこの命令型言語は、B 言語の前身であり、B 言語がその後、今日私たちが使用している C 言語へと進化しました。

BCPL の当時と現在

BCPL が誕生したのは 1966年ですが、この言語の開発は、その作成者である Martin Richards 氏によって今でも活発に進められています。BCPL の最初のコンパイラーは、世界初のタイム・シェアリング・オペレーティング・システムの 1 つ、Compatible Time Sharing System で動作する IBM 7094 システム用に作成されましたが、現在、BCPL は Linux をはじめとする多種多様なシステムで使用できるようになっています。

BCPL は (C 言語に似た) 高級言語ですが、コンパイラーが生成する中間コードは O-code (オブジェクト・コード) と呼ばれていました。O-code は (VM としての) 物理マシンで解釈することができます。あるいは、O-code からホストのネイティブ・マシン言語へとコンパイルすることも可能です。こうしたことができることから、マシンに依存しないというコンテキストで多くの利点がもたらされます。第一に、O-code を物理マシンから抽象化することによって、各種のホストで O-code を簡単に解釈できるようになります。第二に、O-code はマシンのネイティブ・コードにコンパイルできるので、高級言語から O-code へのコンパイラーを開発しさえすれば、O-code からマシンそれぞれのネイティブな命令に変換するコンパイラーを使って高級言語からそれぞれのマシンにネイティブな命令へと変換することができます (タスクが単純化されます)。このマシンに依存しない性質のおかげで BCPL はマシン間で移植が可能であり、さまざまな環境で使えるため、広く使用されるようになりました。

1970年代初頭になると、カリフォルニア大学サンディエゴ校でコンパイル済み Pascal を実行するための VM 手法が開発されました。その中間表現に付けられた名前は P コードです。P コードは、(抽象的な擬似マシン・アーキテクチャーを利用するのではなく) ハードウェアから独立して Pascal コンパイラーの開発を単純化することを目指しました。Forth 言語もまた、VM (具体的には、ゼロ・アドレス、つまりスタック・ベースのアーキテクチャー) を適用しました。

1972年、Xerox PARC は Smalltalk 言語を発表しました。VM を利用して実行される Smalltalk は、オブジェクトの概念を中心に作成された最初の言語の 1 つです。Smalltalk と P コードはどちらも、現在使用されている最も有名な VM ベースの言語の 1 つ、Java 言語に大きな影響を与えています。Java は 1995年、Sun Microsystems によって開発され、Java 仮想マシンという手段により、プラットフォームに依存しないプログラミングの概念を展開しました。それ以来、Java 技術は Web アプリケーションのビルディング・ブロックとなっています。サーバー・サイドのスクリプトからクライアント・サイドのアプレットに至るまで、Java 技術は VM 技術の認識を高めました。そして、JIT (Just-In-Time) コンパイル技術を使ってコードの解釈とネイティブ・コードの実行とを結び付ける新しい技術を導入しました。

VM の概念は、その他多くの言語にも採り入れられています。Erlang 言語 (Ericsson により開発) では Erlang バイト・コードを実行するためだけでなく、ソースの抽象構文木から Erlang を解釈するためにも VM を使用します。軽量の Lua 言語 (ブラジルのリオデジャネイロにあるパナラ・カトリカ大学で開発された言語) に採り入れられているのは、レジスター・ベースの VM です。Lua プログラムを実行すると、プログラムはバイト・コードに変換されてから VM で実行されます。この記事では後で、あらゆる言語に適用できるバイト・コード標準について取り上げます。


アプリケーション仮想化の現在

VM を使用して物理ホストを抽象化するという従来からの一般的な方法は、現在ではさらに進化した形で応用されています。このセクションでは、VM の概念を未来へとつなげる、いくつかの新しいオープンソースのソリューションに目を向けます。

Dalvik VM

Dalvik は、Google が Android オペレーティング・システム用に開発したオープンソースの VM 技術です。Android は Linux カーネルにモバイル機器用のソフトウェア・スタックを統合するようにしたものです (図 2 を参照)。スタック・ベースのアーキテクチャーを利用する多くの VM 技術とは異なり、Dalvik の VM はレジスター・ベースのアーキテクチャーとなっています (アーキテクチャーおよび命令セットについての詳細は、「参考文献」を参照)。スタック・ベースのアーキテクチャーは概念的には単純で効率的ですが、(スタックの保守のために) プログラムのサイズが大きくなるなどの 新たな非効率性が生じる可能性があります。

図 2. Dalvik ソフトウェア・スタックの単純なアーキテクチャー
Dalvik のアーキテクチャー

Dalvik は VM アーキテクチャーであるため、VM が理解するバイト・コードにコンパイルされる前の高級言語に依存しますが、Dalvik では一から開発をやり直すことはしていません。代わりに、Java 言語をそのままアプリケーション開発用の高級言語として使用しています。Dalvik はまた、dx と呼ばれる特殊なツールを利用して、Java クラス・ファイルを Dalvik VM 実行可能ファイルに変換します。この Dalvik 実行可能ファイル (dex) は、VM がパフォーマンスをさらに最適化するために追加で変更することもあります。例えば、JIT コンパイルで dex 命令をネイティブ命令に変換して、ネイティブ・パフォーマンスを引き出すなどです。動的変換とも呼ばれるこのプロセスは、VM 技術のパフォーマンスを向上させる一般的な手法です。

図 2 に示されているように、Linux ユーザー空間内では Dalvik 実行可能ファイルが (VM のインスタンスと併せて) 単独のプロセスとして分離されます。Dalvik VM は (独立したプロセスでの) 複数の VM を同時に実行できるように設計されています。

Dalvik VM は標準 Java ランタイムには実装されないため、Java のライセンスを引き継ぎません。代わりに、Dalvik は Apache 2.0 ライセンスの下に公開されたクリーンルーム実装となっています。

Parrot

興味深いオープンソースの VM プロジェクトとしては、Parrot も挙げられます。Parrot もまた、動的言語を効率的に実行するように設計されたレジスター・ベースの VM 技術です (動的言語とは、通常はコンパイル時に行われるような特定の処理 (型システムの変更などの処理) を実行時に行う言語です)。

Parrot は当初、Perl6 のランタイムとして設計されましたが、今では多くの言語に対応する柔軟なバイト・コード実行環境となっています (図 3 を参照)。Parrot がサポートする入力形式はさまざまです。例えば、コンパイラー・ライターに便利な PAST (Parrot Abstract Syntax Tree)、高級な表現として人間が作成することも、コンパイラーが自動的に作成することもできる PIR (Parrot Intermediate Representation)、そして低級よりの表現ながらも、人間とコンパイラーの両方にとって便利な PASM (Parrot Assembly) などの形式がサポートされていて、それぞれの形式が Parrot VM 上で Parrot バイト・コードに変換されて実行されます。

図 3. Parrot VM の単純なアーキテクチャー
Parrot VM のアーキテクチャー

Parrot はいくつもの言語をサポートしますが、Parrot をとりわけ興味深いものにしている特徴は、これが静的言語と動的言語の両方をサポートすることです。これには、関数型言語固有のサポートも含まれます。リスト 1 に、PASM の単純な使用例を示します。Parrot を Ubuntu でインストールするには、以下のような apt-get を実行します。

sudo apt-get install parrot

以下のセッションに示されているのは、Parrot の単純なストリング操作プログラムです。Parrot はこのコードをアセンブリー言語で実装しますが、これは皆さんが使い慣れているようなアセンブリー言語よりも遥かに機能が充実しています。Parrot での命令は dest,src 構文を使用します。従って、リスト 1 ではストリング・レジスターにテキストをロードし、length 命令によってストリングの長さを判断して、整数レジスターにストリングをロードし、print 命令によって引数が標準出力 (stdout) へ出力され、concat がストリング連結を実装しています。

リスト 1. PASM の例
$ more test.pasm
set	S1, "Parrot"
set	S2, "VM"
length	I1, S1
print	I1
print	"\n"

concat	S3, S1, S2
print	S3
print	"\n"

end

$ parrot test.pasm
6
ParrotVM
$

Parrot に豊富な命令セットがあることは、皆さんにもわかるはずです (詳細は「参考文献」を参照)。このプロジェクトの作成者たちは、コーディングを容易にして Parrot VM のコンパイラーを作成しやすくするために、ミニマリズムよりも機能の豊富さを優先させています。

上位レベルの抽象化を提供する PASM と比べても、上級プログラマーにとってさらに使いやすいのは PIR です。リスト 2 に、PIR で作成して Parrot VM によって実行されるプログラムの例を記載します。この例が宣言する square という名前のサブルーチンは、数値を 2 乗して結果を返します。このプロセスは、結果を出力する main サブルーチン (Parro に対し、このサブルーチンを最初に実行するように指示する :main というラベルが付けられています) によって呼び出されます。

リスト 2. PIR の例
$ more test.pir
.sub square
  .param int arg
  arg *= arg
  .return(arg)
.end

.sub main :main
  .local int value
  value = square(19)
  print value
  print "\n"
.end
$ parrot test.pir
361
$

マシンに依存しないだけでなく、高い効率性も追求するアプリケーション開発にとって、Parrot はリッチなアプリケーション仮想化環境を提供します。しかも、Parrot 用に設計されたコンパイラー・フロント・エンドは、C、Lua、Python、Scheme、Smalltalk をはじめ、多数の言語によってサポートされます。


アプリケーション仮想化のその他の使用例

ここまでは、最近の 2 つの具体的な例を含め、アプリケーション仮想化がこれまでどのように使われてきたかを説明してきました。具体的な 2 つの例のうち、Dalvik は、現在の携帯電話でのアプリケーション開発で使われています。そして、もう 1 つの Parrot は、静的言語と動的言語両方のコンパイラー・ライターに効率的なフレームワークを提供します。けれどもアプリケーション仮想化の概念は、これまで説明してきた以外のさまざまな分野でも実装されています。

そのなかでも特に興味深いアプリケーション仮想化の例は、皆さんが今まさに使っているコンピューターで動作している可能性があります。BIOS の代わりとして新しく導入された EFI (Extensible Firmware Interface) を採用しているシステムでは、ファームウェア・ドライバーを EBC (EFI Byte Code) と呼ばれるものに実装することができます。それにより、これらのシステムのファームウェアには、EBC イメージがロードされると呼び出されるインタープリターが組み込まれます。この概念は、Sun Microsystems が Forth (独自の VM を組み込んだ言語) を使用して Open Firmware に実装しました。

ゲームの世界においては、アプリケーション仮想化の使用は今に始まったことではありません。最近の多くのゲームでは、プレイヤー以外のキャラクターの振る舞いや、ゲームのその他の側面のスクリプトを、バイト・コードを実行する言語 (例えば Lua など) を使用して組み込んでいます。けれども、ゲームでのアプリケーション仮想化の概念は、実際には遥か昔に遡ります。

Zork などのテキスト・ベースのアドベンチャー・ゲームを導入した企業である Infocom は、マシンに依存しないことの価値を 1979年に見出しました。そこで Infocom が作成したのが、Z-machine (Zork にちなんで付けられた名前) と呼ばれる VM です。Z-machine は、アドベンチャー・ゲームを他のアーキテクチャーに容易に移植するための VM として、ゲーム全体を新しいシステムに移植しなくても、Z-machine を表すインタープリターを移植するだけで、ゲームを移植できるようにしました。この機能により、サポートする言語が違っていたり、マシンのアーキテクチャーがまったく異なるシステムに移植したりする場合でも、そのプロセスが単純化されたわけです。Infocom の最終目標は、アーキテクチャー間での移植に伴う当時の苦労を軽減することでしたが、その取り組みは移植を単純化するために引き続き行われています。その結果、これらのゲームは新しい世代のアーキテクチャーでも (モバイル・プラットフォーム上のアーキテクチャーでさえも) 利用できるようになっています。

ゲームでのその他の VM のアプリケーションには、ScummVM (SCUMM (Script Creation Utility for Maniac Mansion) スクリプト言語 (1987年に作成) を対象とした VM 環境を提供します) もあります。SCUMM は、グラフィカル・アドベンチャー・ゲームの開発を簡易化するために LucasArts によって開発されました。ScummVM は現在、さまざまなプラットフォームで多数のテキスト・アドベンチャー・ゲームとグラフィカル・アドベンチャー・ゲームを可能にするために使用されています。


さらに詳しく調べてください

プラットフォーム (またはシステム) 仮想化が、サーバーとデスクトップ両方のプロビジョニングおよび管理の方法を変えているように、アプリケーション仮想化はこれからも、ホスト・システムからアプリケーションを抽象化する効率的なメカニズムを提供し続けていくはずです。アプリケーション仮想化が現在よく使用されていることを考えると、ソフトウェアおよびハードウェア双方の進化によって、このアプリケーション仮想化の手法が今後さらに柔軟かつ効率的になっていくのが楽しみです。

参考文献

学ぶために

製品や技術を入手するために

  • Dalvik は、Android オペレーティング・システム用の VM 環境です。Dan Bornstein によって開発された Dalvik は、現在 Android の一部として Google で保守管理しています。Dalvik マシンのバイト・コード (ユーザー・マニュアルに記載) に目を通して、Dalvik マシンの詳細を学んでください。また、「Android 開発入門」(Frank Ableson 著、developerWorks、2009年5月) でも、Dalvik の詳細を学べます。
  • Parrotは、静的言語および動的言語を Parrot バイト・コードのさまざまな中間表現を使用して効率的に実行するように設計された VM です。Parrot はオープンソースとして入手可能で、しかもさまざまな言語で使用できます。Parrot の命令セットについて詳しく学ぶには、このセットに含まれている命令コードを調べてください。
  • アプリケーション VM は、ゲーム開発の世界でよく使用されています。アプリケーション VM がいち早く導入された例は、Infocom によるテキスト・アドベンチャー・ゲーム (Zork など) です。Z-machine と呼ばれる Infocom VM、そしてさまざまなプラットフォームを対象としたインタープリンターについて学んでください。アプリケーション VM の例には、LucasArts のグラフィカル・アドベンチャーで使用されている SCUMM もあります。SCUMM は ScummVM というオープンソースとして実装されるようになり、古いゲームを最近の新しいハードウェアで蘇らせています。
  • ご自分に最適な方法で IBM 製品を評価してください。評価の方法としては、製品の試用版をダウンロードすることも、オンラインで製品を試してみることも、クラウド環境で製品を使用することもできます。また、SOA Sandbox では、数時間でサービス指向アーキテクチャーの実装方法を効率的に学ぶことができます。

議論するために

  • My developerWorks コミュニティーに加わってください。ここでは他の developerWorks ユーザーとのつながりを持てる他、開発者が主導するブログ、フォーラム、グループ、ウィキを調べることができます。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux
ArticleID=696827
ArticleTitle=アプリケーション仮想化の過去と未来
publish-date=07082011