余談


開発の動機

スレッドを移動させてみようかな〜と思ったのは、ひとつは JavaHouse メイリングリスト に慶応所研究室の 勝野さん が書いた 記事 ([JavaHouse-Brewers:9914]) です。 「スレッドの serialize がうまくいかない」という内容でした。

もうひとつは、(株)アルファシステムズの岡田さんが Kafka のメイリングリストでアナウンス (kafka-user:29) されたページ 「各社エージェントの機能比較」 です。 このページでは、各社の移動エージェント記述ライブラリ ( Voyager, Aglets Workbench, Odyssey, Kafka ) が比較されています。

各ライブラリの API を見てびっくり、移動先では、システム またはユーザが指定したメソッドが呼び出されるだけです。 例えば Voyager での移動の記述はこんな感じです。

moveTo(移動先, String メソッド名, Object 引数)
Aglets Workbench では、移動後に callback メソッド
public void onArrival()
が呼び出されるようです。

つまらな過ぎる!実行コンテクストは捨てるのか? プログラミングインタフェースとして透過性が低くて醜い!

ということで、スレッドが移動できれば、移動エージェントも 通常の移動しないプログラムとほぼ同じ作法で記述できるな、 と思い立ちました。


Native methods

得られるもの, 失うもの

ただ、各社とも醜いプログラミングインタフェースを採用して いるにはわけがあるわけです。実行コンテクストをともなった スレッドの移動は、Java では実現できないのです。

JDK 1.1 より、 Reflection の API が提供されるなど、自己反映的な操作を行いやすくはなりました。 それでもまだ、スレッド移送を実現するためには、C言語を使っ て JVM を拡張する必要があります。つまり、native methods を書く必要があります。

native methods を使えば何でもできますが、反面、様々なデ メリットがあります。Java でのソフトウェア開発で、native methods を使用することのデメリットは許容されないことが多 いです。

native methods を使用することで、 次のように、Java の利点がある程度損なわれます。

インストールが必要となる。
Java を採用する理由として インストール作業が不要か非常に簡単であることが重要な場合は多い。
アプレットから利用しにくい。
Web ブラウザ上で動かせることが重要な場合は多い。

native methods を使用することで得られるものと失うものが 秤にかけられます。移動エージェント記述ライブラリを開発し ている各社にとって、失うものの方が大きかったのでしょう。 理解できます。

私は、native methods を利用しても何でもいいから スレッド移送を実現したいと思いました。

使いどころ

native methods を使えば何でも出来る、高速化だってし放題 だろう、というのはその通りですが、私は「native methods でなければ実現できない部分」にのみ最小限使用しようとしています。

高速化のために native methods を使う場合は、はなから C や C++ で書くことも含めて慎重に検討すべきです。Java 部分 が C の wrapper にならないように…


デバッグ

MOBA のデバッグはずいぶんと困難でした。 理由はおよそ次の通りです。 Java と C の混合システムであることは、次をもたらしました。 native methods のデバッグに Java デバッガは無力ですし、 C デバッガは、バイナリで供給されている JDK 内部は追えません。 デバッガで追った先が JDK の内部だったりすると、 バグの発見はかなり困難です。

native methods は C で記述するわけですが、Java のメソッ ドを書く以上、当然 GC を考慮しなければなりません。C 側で まだ使いたいオブジェクトが GC で回収されていた、なんてこ とも経験しました。

profiling については状況は絶望的です。native methods を Java の profiling 対応に書き換えましたが、C の関数と Java のメソッドが呼び合う状況ではまだ動作がおかしいです。 C のレベルで profiling することが考えられますが、このためには JDK を自分でコンパイルする必要があります。これにはまだ挑戦していません。

multithreading (以下 MT) 関係でもいろいろと悩まされまし た。native methods 中で、MT と相性の悪い signal をどうし ても利用する必要があり面倒だったり、 これまた MT safety と相性の悪い setjmp(), longjmp() が 必要で困ったり…

MT と言えば、デバッグ時、非同期 GC にもずいぶん混乱させられました。


Back to


Copyright 1996,1997,1998,2003 首藤 一幸
<shudoh at muraoka.info.waseda.ac.jp>