• 検索結果がありません。

Java オンラインプラグイン特有の課題

!

"#%$

&#')(+*-,/.0+.1)2+3547689 &;:+()<>=?2@BACD98FE

21)8GH=?2@I.13.198

J

!

"#+%$

+KL

&NM2+(G=2@-O3P)0098.1E

QP7R1)9)=SGT.@I1U6)R.1V)6WX98

+

+KL

&NMQ(G=2@-O3P)0098.1E

21819)=YG.@I.1V)6W598 Z

?

J

+KL

&;[F(19U=SGH=2U@\.13.1)98 +K]!

"#+%$

^ ^

図30: Considerations for JIT compilation.

メソッドの場合、実行時コンパイラは呼出先をインライン展開する可能性があある。旧コードがイ ンライン展開されたままでは新コードを実行することができない(図30)。

これらの対応としては、呼出元を非最適化コード(中間コード)に戻すしかない。

次章では上記を考慮したJavaオンラインプラグイン機構について説明する。

5.6.4 インライン展開の取り扱い

Java VM内のJITコンパイラはJava中間コードを機械語に変換する。これは中間コードを逐次

翻訳して実行することに比較して大幅なパフォーマンス向上を実現する。

さらに、JITコンパイラは、可能であれば、メソッド呼出をインライン展開する。

リアルタイム通信システムにおいて、これらの機能は、性能向上のために大いに役立つ。

しかし、インライン展開は、オンラインプラグインの観点からは問題となる。旧Javaクラスのメ ソッドの呼出しが、JITコンパイラによりインライン展開されている場合には、中間コードを差し 換えても旧メソッドが動き続けることになるため、該当する部分についてインライン展開を解除す る必要がある。

図31はインライン展開の解除手順を表す。

まず、図31 (a)は、インライン展開が行なわれるまえの状態であり、メソッドAがメソッドBを

呼び出している様子を示す。図中の矩形はメソッドコードを表し、callはメソッド呼出を表す。

図31 (b)はメソッドBがメソッドAのコード中にインライン展開された様子を表す(B’)。また、

5.6. Javaオンラインプラグイン特有の課題 67

! "$#%

&'(

)

*+

+-,

)

.&/

012

! "$#%

3

+-,

)

4

.&/

+ +

4

.&/

+

4

.3/

+657 08

59+65:;0

/

<

59+

2 ! "$#%

3

+

+

+65: 08

=

図 31: メソッドのインライン展開の解除方法

同時に補償コードを生成する。補償コードは、元のメソッドBの呼出を行った後、元の制御フロー (A2)へ復帰する。

図31 (c)はクラスのダイナミックロードによりメソッドBを置き換えるメソッドがロードされた

後の状況を示す。メソッドBがメソッドnew Bにより置き換えられたため、インライン展開した コード列B’の先頭を書き換え(jmp)、インライン展開したコード列B’に到達すると必ず補償コー ドへ分岐するようにする。

これにより、メソッドAからインライン化されているB’を実行しようとすると、補償コードが 実行される。補償コード内ではメソッドB呼び出しが行われ、正しくnew Bが実行されるように なる。

Javaプラグイン機構の開発当初、HotSwap機能はJITコンパイラを停止させた状態でないと利 用できなかった。これは、インラインの解除等、付加的な機能が必要となるためである。しかし、そ れでは処理性能が大幅にダウンするため、HotSwap開発者に要望を出し、JITコンパイラ動作時も

HotSwapが可能となるような最新版の仮提供を受けて開発評価を進めた。

現在、HotSpotVMの最新版ではJITコンパイラ動作時もHotSwapが可能となっている

なお、オンラインプラグイン実行後に、インライン展開部分は使用されなくなることから、パフォー マンスの低下の可能性がある。これについては、第5.8章にて評価結果を示す。

5.6.5 スタティックデータの変更方法

Javaオンラインプラグイン機構におけるスタティックデータの追加手順を以下に示す。

(1) Java VMは、スタティックデータ(class data)を追加するためのメモリエリアを確保する。

Javaの一般的な実装では、全てのクラスデータは一箇所にまとまって配置される。そのため、

新たに確保した領域には、既に存在していたデータと新たに追加したデータの双方が格納でき るだけの領域が確保される。

(2) プラグインローダは、旧データエリアの内容を新エリアにコピーする。

(3) 旧データへの参照は、新データへの参照に置き換えられる。

オブジェクトへのリファレンスが複数ある場合は、VMはヒープエリア内を追跡して置換えを 行なう。

(4) 新プログラムは追加されたデータエリアをアクセスする。

この手順において、データの一貫性を損なわないために、(2)と(3)はアトミックアクションとし て実行される。

スタティックデータの変更や削除も同様の手順で実行される。しかしこれらのケースでは、コー ドとデータの双方の修正について一貫性を保つ必要があるため、(2)〜(4)の手順がアトミックアク ションとして実行される。

これは、新コードによる旧データのアクセス、および、旧コードによる新データのアクセスの双 方が矛盾を起こす可能性があるためである。

5.6. Javaオンラインプラグイン特有の課題 69

5.6.6 初期設定処理

プラグイン投入の契機に、初期設定用のメソッドを実行したいことがある。例えば、スタティック なクラスデータを追加したが、それに初期値を設定したい場合などである。

初期設定処理は、交換機におけるC++オンラインプラグインにおいて重要な役割を果たしてい た。初期設定処理により、データの値の設定、新たなバッファプールの生成、エントリアドレスの 登録などが可能である[5, 14]。

この機構は、予めプログラマによって記述された初期設定用のルーチンを、新プログラムが実行 されるように切替えられる前に起動するものである。Javaオンラインプラグイン機構も同様の機能 を具備する。

プラグインエージェントは、プラグインファイル内のplugInitという名前のメソッドをサーチし、

HotSwap実行時に起動する。

現状、HotSwap機能の制限により、plugInitが必ず他のメソッドに優先して実行される保証はな く、この点は改良の必要がある。

5.6.7 安全なオペレーション

オンラインプラグイン実行後に重大な障害が発生したとしても、システムはサービス停止を引き 起こしてはならない。異常を検出したら、追加修正されたプログラムは取り除かれ、元の状態に復

帰する(プラグアウト)。プラグアウトは、システムが異常発生によりリスタートした場合、あるい

は、保守者が異常を見つけてコンソールからプラグアウトコマンドを投入した場合に実行される。

修正されたプログラムが無限ループのようなクリティカルなエラーを含むならば、前者(システム 異常によるプラグアウト)が実行される。

システムが再起動まで至らないような軽微な問題が発生した場合には、後者(保守者指示による プラグアウト)が行なわれる。

監視期間は、オペレータ指示により確実にプラグアウトを行なうために設定される。この期間中、

オペーレータは、修正箇所に関わる、システムのチェック、試験の実施、警報の監視を行なう。もし 異常を検出した場合、保守者はプラグアウトコマンドを投入する。プラグインエージェントは、プ ラグインマネージャにより、HotSwapの機能を利用して、プラグインされたプログラムへのリンク を元の状態に戻す。

もし、保守者が、そのシステムが正常であると判断した場合、プラグイン処理を完了させるため のプラグインコミットコマンドを実行する。このコマンドにより、プラグインエージェントは、ディ スク上のメインディレクトリに存在するJavaのオリジナルのクラスを、プラグインディレクトリに あるプラグインファイルに含まれるクラスで置き換える。プラグインディレクトリに保存されてい たプラグインファイルは削除される。その後、システムの再起動が起こった場合、プラグインファ イルが組み込まれた状態で、システムは立ち上がることになる。

システムがプラグインコミットの前に再起動するならば、プラグインファイルは取り除かれなけ ればならない。なぜならば、プラグインファイルの修正部分に問題が含まれる可能性が高いからで ある。この状態において、オリジナルのクラスはメインディレクトリに存在し、修正したクラスが

プラグインディレクトリに存在する。システムが再起動する際には、プラグインディレクトリは無 視される。すなわち、プラグインファイルを含まない状態でシステムは起動することになる。

オペレータの保守操作により、プラグインの状態を確認することが可能である。そのような情報 は、プラグイン管理テーブルにおいて管理される。