1 / 22

標準 Java 仮想機械上で 動的 にメンバーの追加 を行う機構の提案

標準 Java 仮想機械上で 動的 にメンバーの追加 を行う機構の提案. 東京工業大学 早船 総一郎 千葉 滋. 動的な振る舞いの変更. 既に実行しているプログラムの振る舞いを変更 サーバを止めずに セキュリティパッチを適用 性能を調査 対話的開発. 切り替え. 新しいコード. 古いコード. サーバー. 典型的な利用シナリオ. オフラインで型検査等を実行 コンパイル済みのクラス定義を準備 対話的に新しいクラス定義を送り込む RMI や JDWP を利用. 古いコード. ユーザ ホスト. サーバー. 新しいコード.

ward
Download Presentation

標準 Java 仮想機械上で 動的 にメンバーの追加 を行う機構の提案

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 標準 Java 仮想機械上で動的にメンバーの追加を行う機構の提案 東京工業大学 早船 総一郎 千葉 滋

  2. 動的な振る舞いの変更 • 既に実行しているプログラムの振る舞いを変更 • サーバを止めずに • セキュリティパッチを適用 • 性能を調査 • 対話的開発 切り替え 新しいコード 古いコード サーバー

  3. 典型的な利用シナリオ • オフラインで型検査等を実行 • コンパイル済みのクラス定義を準備 • 対話的に新しいクラス定義を送り込む • RMI や JDWP を利用 古いコード ユーザホスト サーバー 新しいコード

  4. 動的なクラス定義の変更 • メソッドの中身の変更 • シグネチャは変わらない • メンバーの追加 • 仮想関数テーブルが更新 class Position { void move(int i){ x = x + i; } } class Main{ void action (Position p) { p.move(1); }} 追加 class Position { void move(inti){ x = x + i; } int distance(inti,int j){ return sqrt((x – i)^2 + (y – j)^2); } } 変更 class Main { void action (Position p) { p.distance(0,0); }}

  5. HotSwap による動的な振る舞いの変更 • 標準 Java 仮想機械で提供 • メソッドボディの内容を異なるものに変更 • メンバーの追加は不可 • 最適化のため? class Position { void move(int i){ x = x + i; } } class Main{ void action (Position p) { p.move(1); }} class Position { void move(inti){ x = x + i; } int distance(inti,int j){ return sqrt((x – i)^2 + (y – j)^2); } } 変更 class Main { void action (Position p) { p.distance(0,0); }}

  6. 提案:動的なメンバーの追加を可能に • 標準 Java 仮想機械を利用 • JavaAgent, Javassistを利用 • プログラムの監視、バイトコードの変換 • RMI による対話的な更新 本システム Javassist RMI Java Agent ユーザホスト 新しいコード 古いコード

  7. 実現:ロード時に汎用性の高いメンバーを準備実現:ロード時に汎用性の高いメンバーを準備 class Main{ void action (Position p) { p.move(1); }} class Position { void move(int i){x = x + i;} } class Position { void move(inti){x = x + i;} } 追加 変換 blank$ (…){ 空 } class Position { void move(inti){x = x + i;} int distance(inti,int j){ return sqrt((x – i)^2 + (y – j)^2); } } class Main { void action (Position p) { p.distance(0,0); }} class Main{ void action(Position p) { }} class Position { void move(int i){x = x + i;} } blank$ の呼び出し blank$ (…){/* distance の処理 */}

  8. メンバーを追加してからロード • ロード時なら標準 Java 仮想機械でも可能 • 汎用性の高いメソッド • 返り値の型、引数の型は Object と Object の配列に • 重複しないようにメソッド名を準備 class Position { void move(int i){x = x + i;} } ロード時に 追加 class Position { void move(inti){x = x + i;} } public Object blank$ (Object[] objects) { return null; }

  9. 実行中にメソッドを追加 • distance メソッドを追加 • action メソッドが distance を呼ぶ class Position { void move(inti){x = x + i;} int distance(inti,int j){ return sqrt((x – i)^2 + (y – j)^2); } } class Main { void action (Position p) { p.distance(0,0); }} class Main{ void action(Position p) { }} class Position { void move(int i){x = x + i;} } blank$ の呼び出し blank$ (…){/* distance の処理 */}

  10. 追加された側のクラスの変換 • 追加するメソッドの中身を準備しておいたメソッドにコピー • 実行時に型変換するコードを挿入 class Position { void move(inti){x = x + i;} int distance(inti,int j){ return sqrt((x – i)^2 + (y – j)^2); } } public Object blank$(Object[] objects) { } 型変換するコード int → Object Object[] → int, int return sqrt((x – i)^2 + (y – j)^2); class Position { void move(int i){x = x + i;} } blank$ (…){/* distance の処理 */}

  11. 呼び出し側の変換 • 追加したメソッドは実際には存在しない • blank$ を呼び出すように変換 class Main { void action (Position p) { p.distance(0,0); }} p.blank$(new Object[] { 0, 0}); class Main{ void action(Position p) { }} class Position { void move(int i){x = x + i;} } blank$ の呼び出し blank$ (…){/* distance の処理 */}

  12. オーバーライドの考慮 class Data { void move(int i){x = x +i;} int distance(int i,int j){ return ((x – i)^2 + (y – j)^2)^(1/2); }} • メソッドにはオーバライドがある • 呼び出される対象が変化 class Position { void move(int i){x = x +i;} } main (Position p) { p.distance(0, 0); } 呼出? class Rect { void move(int i){x = x +i;} int distance(int i,int j){ return ((x – i)^2 + (y – j)^2)^(1/2); }} class Circle{ void move(int i){x = x +i;} }

  13. 汎用性の高いメソッドを準備 • オーバーライドされているメソッドを呼び出しておく class Circle{ void move(int i){x = x +i;} } class Position { void move(int i){x = x +i;} } 呼出 public Object blank$ (Object[] objects) { return super.blank$(objects); } blank$ メソッド

  14. 追加の実現 class Position { void move(int i){x = x +i;} } • 各クラスにメソッドを準備 • 意図しないオーバーライド • blank$ メソッドの呼び出し • オブジェクトの動的な型 • Circle のblank$ が呼び出される class Circle{ void move(int i){x = x +i;} } 呼出 public Object blank$ (Object[] objects) { } blank$ メソッド main (Position p) { } p.blank$(new Object[] { 0,0 }); 型変換するコード 呼出 distance の処理

  15. 呼び出し側の変換 class Position { void move(int i){x = x +i;} } • オーバーライドに対する制御 • 型の確認 • 呼び出すメソッドの切り替え main (Position p) { } class Rect{ void move(int i){o = o +i;} int distance(int i,int j){ return ((x – i)^2 + (y – j)^2)^(1/2); } } if(p instanceof Rect){ p.distance(0,0); } else if(p instanceof Position){ p.blank$(new Object[] { 0,0 }); } else { p.distance(0,0); } 呼出 public Object blank$ (Object[] objects) { } 型変換するコード blank$ メソッド distance の処理

  16. フィールド、コンストラクタの追加 • メソッドと似たような処理 class Position { void move(int i){x = x +i;} } 準備 class Position { void move(int i){x = x +i;} } main (Position p) { p.move(1); } blank$ フィールド blank$ コンストラクタ 変更 追加 class Position { void move(int i){x = x +i;} } main (Position p) { } blank$ のアクセス blank$ の呼び出し blank$ フィールド blank$ コンストラクタ

  17. ユーザーが追加や変更を指示する方法 • 対話的に新しいクラス定義の変更を送る • メンバーに関しては追加のみを許し、削除を許していない • 追加が行えるタイミングとしては標準の Hotswap と同様である

  18. 実験 • マイクロベンチマークを作成する • 空のメンバーの準備 • いくつかの異なるクラスをロードする時間を計測 • オーバーライドに対する制御 • 本システムで追加をしたメソッドを呼び出す時間を計測 • 実験環境 • OS: Windows7 • CPU: Intel Core2Quad 2.67GHz • メモリ: 4GB

  19. 実験:空のメンバーの準備 • クラス一つあたりのロード時間 • 本システム不使用:約0.26ms、本システム利用:1.33ms • 4~5倍のオーバーヘッド

  20. 実験:オーバーライドに対する制御 • 一回のメソッド呼び出し • 型の確認なし:5.262ns、型の確認あり:10.04ns • 2倍のオーバーヘッド

  21. 関連研究 • Dynamic Virtual Machine [‘00 Malabarba ら] • 改造した Java 仮想機械上で変更を行う機構 • 特別なクラスとクラスローダーを定義 • 一般的に利用されている標準 Java 仮想機械を用いた上で実現する方法が望ましい • Envelope-Based weaving [‘05 Bockisch ら] • 事前にメンバーを準備しておく手法 • Aspect 指向言語の織り込みを支援 • クラス定義の変更には対応していない

  22. まとめ • 標準 Java 仮想機械上で動的にメンバーの追加を行う機構を提案 • ロード時に各クラスにメンバーを準備 • 準備しておいたメソッドを利用して、型変換のコードを含め追加 • 呼び出し側の変換 • オーバライドの考慮 • マイクロベンチマークによる実験 • オーバーヘッドの計測

More Related