【新・言語進化論】言語選択の分かれ道
第3回:特許文献の検索サーバにJavaを選んだワケ
著者:Jurabi 高橋 芳太郎
公開日:2007/11/15(木)
共有ライブラリを使用することが可能
JavaにはJNI(Java Native Interface)というAPIが提供されており、簡単なラッパーを作成することでC/C++などで作成した共有ライブラリを使用することができる。今回使用した検索エンジンHyper Estraierにはすでにこのラッパーが提供されている。また、必要なAPIのみを使用するラッパーならば、自分で作成してもそれほどのコストは掛からないので、要件を満たしているといえる(JNIについての詳細は下記URLを参照)。
Javaで作成されたクライアントとの通信(LAN内)の仕組みを容易に実現可能
Javaは言語レベルでRMI(Remote Method Invocation:直訳すれば遠隔メソッド呼び出し)という通信手段を提供している。RMIを使うと他のVMにあるオブジェクトのメソッドを呼び出すことが可能になる。
下図のようにサーバ側のオブジェクトは自身をbindメソッドを使用してrmiregistryに登録する。クライアントはlookupで登録されているオブジェクトを検索する。検索に成功するとサーバ側オブジェクトと同一のインターフェースを持つスタブオブジェクトが返却される。以降はそのスタブを通して、サーバとやり取りが行われる。
RMIはインターネットを介した通信ではファイアウォールなどでアクセスが拒否される可能性が高いが、そのような制限のないLAN内の通信にはその利用の簡便さから非常に適しているといえる。
元々Webアプリケーション内部で動作させていたコードを負荷分散のためにいくつかのサーバに分けることも、RMIのラッパークラスを作成しサーバ側に移行した元のクラスに処理を委譲することで簡単に行える。つまり、性能的に同一サーバでの処理が不可能とわかった時点でサーバを分けることも十分可能である(RMIについての詳細は以下のURLを参照のこと)。
サーバ自体が使用するメモリ使用量は抑えたい
JVMでは初期起動時に通常10MB程度のメモリを消費する。全文検索サーバでは1ノードに対してJVMが2〜4ほど起動することになるので、合計で40MB程度のメモリ使用量になる。これは、全体のメモリ4GBに対して1%程度であるので、あまり問題にならないといえよう。
ある程度の性能
JavaはVMを使用しているため初期起動にはかなりの時間がかかるが、サーバとしての使用を前提にした場合は初期起動の遅さは問題にならない。通常の処理は、JIT(Just In Time Compiler)や、世代別ガーベージコレクション(GC)などで飛躍的に性能が向上しており、現在ではC++と比べてもそれほどの性能差はない。それを証明するベンチマークもさまざま公開されており、性能についても問題ないといえよう。
堅牢な動作
Javaは次の3つの理由で堅牢なシステムを安価に作成することができる。
堅牢なシステム1:メモリリークが発生しにくい
C++のスマートポインタによる方式は、メモリの参照数を保持しておき参照数が0になると解放するというものだが、この方式だと親と子が相互に参照を持ち合う場合(循環参照)にメモリリークが発生するという問題が起きる。
JavaのGCは最上位のノードから該当のメモリが参照されていない場合に解放するという方式を取っているため、循環参照の場合にメモリリークが発生することがない。
堅牢なシステム2:アプリケーションが異常終了しにくい
VM上で動作しているために、何か問題が発生した場合も最上位で例外をキャッチすればそのまま処理を継続させることができる(ファイルやデータベースなどのリソースの不整合の場合は速やかに落とすべきだが)。
C/C++ではメモリリークや想定外の状態が起きるとサーバが異常終了するので、検証試験に多大な労力が発生する。Javaではこれらの試験をほとんどやらなくてよいため、テスト工数をかなり削減できる。
堅牢なシステム3:コードを乗っ取られにくい
バッファーオーバフローやprintfストリングなどで実行コードを書き換えることができない。このため、これらを検知するための静的チェックをかける必要や、これらに対する堅牢性を保証するテストを行う必要がない。
これらのことからJavaは堅牢でスケーラビリティの高いサーバを安価に作成することに非常に適した言語といえるだろう。 次のページ