Document

Survey
Portable Resource Control in Java
The J-SEAL2 Approach
hayami
※W. Binder, J. Hulaas, A. Villazón, and R. Vidal
(OOPSLA-2001)
2015/10/1
全体ミーティング
1
J-SEAL2の概要
モバイルエージェント向けマイクロカーネル
Pure Java
階層的なドメイン
ドメイン単位で制御
ドメイン間の通信,安全な終了,…
さらに資源管理機能を付加
CPU,ヒープメモリの使用量を制限
バイトコード変換で実現
2015/10/1
全体ミーティング
2
階層的なドメイン
Untrustedな
MO3は,service
へのアクセスと
使用する計算機
資源が制限され
るべき
2015/10/1
全体ミーティング
3
資源管理を行う背景
Javaには資源管理が不足
計算機資源(CPU,メモリ)独占の可能性
DoSアタックの危険性
想定するアプリケーション
拡張可能なデータベース
Webブラウザ
2015/10/1
全体ミーティング
4
目的
複数のモバイルエージェントが安全に共存
する基盤を提供
資源の独占を防止
あくまでPure Java
2015/10/1
全体ミーティング
5
アプローチ
バイトコード変換
対象プログラム中に資源管理用コードを挿入
利点
ポータビリティを損なわない
JITが利用できる
欠点
高オーバーヘッド
管理の精度
2015/10/1
全体ミーティング
6
目次
資源管理のためのAPI
バイトコード変換による実装
実験
関連研究・まとめ
2015/10/1
全体ミーティング
7
資源管理のためのAPI
2015/10/1
全体ミーティング
8
管理対象とする計算機資源
CPU_RELATIVE:相対的なCPU時間(~%)
MEM_ACITVE: heapメモリ(~MB)
THREADS_ACTIVE
THREADS_TOTAL
DOMAINS_ACTIVE
DOMAINS_TOTAL
2015/10/1
全体ミーティング
9
資源を操作するAPI~Res~
public final class Res {
public static final int
CPU_RELATIVE = 0, MEM_ACTIVE = 1,
THREADS_ACTIVE = 2,
THREADS_TOTAL = 3, DOMAINS_ACTIVE = 4, DOMAINS_TOTAL = 5;
public static Res getCurrentRes(int type);
public int getType();
public long getLimit();
public long getUsage();
public Res split(long limit);
資源のsplit
public void setLimit(long limit);
public void combine();
}
2015/10/1
全体ミーティング
10
資源の分割(split)
親は自分に割り当てられた資源の中から
いくらかを子に分け与える (split)
親,子,孫,…の資源割り当ての総和は一定
2015/10/1
全体ミーティング
11
Class ResSet
•6種類のResを一括してドメインに関連付けるための補助クラス
public final class ResSet {
public static ResSet getCurrentResSet();
public ResSet copy();
public Res getRes(int type);
public void setRes(Res r);
public void combine();
}
2015/10/1
全体ミーティング
12
ドメイン操作のAPI~Seal~
public class Seal { // implements Serializable, Runnable
}
public static void unwrap(WrappedSeal wrapped,
String sealname,
ResSet resources);
...
• wrapされたドメイン (serializeされたモバイルエージェント)
wrappedに,計算機資源resourcesを割り当て,名前
sealnameで実行を開始する
2015/10/1
全体ミーティング
13
資源割り当ての例
childB
childA
2015/10/1
全体ミーティング
14
APIを使った記述
long MB = 1024*1024;
ResSet rP = ResSet.getCurrentResSet();
Res cpu = rP.getRes(Res.CPU_RELATIVE);
Res mem = rP.getRes(Res.MEM_ACTIVE);
ResSet rA = rP.copy();
long cpuA = (long)(cpu.getLimit()*0.75);
rA.setRes(cpu.split(cpuA));
ResSet rB = rP.copy();
rB.setRes(mem.split(10*MB));
親のCPU資源
の75%をsplit
親のメモリ資源
から10MBをsplit
Seal.unwrap(childA, nameOfChildA, rA);
Seal.unwrap(childB, nameOfChildB, rB);
2015/10/1
全体ミーティング
childAとchildB
の実行開始
15
バイトコード変換による実装
2015/10/1
全体ミーティング
16
バイトコード変換のタイミング
classloaderを利用し、ロード時に変換
classfiles
find “Foo.class”
classloader
loadClass(“Foo”)
Transform
“Foo.class”
JVM
2015/10/1
全体ミーティング
17
定義: ドメインのtype
各ドメインは管理する資源に応じて4つに分
類される
NO-ACC: 資源管理なし。バイトコード変換なし
CPU-ACC: CPU資源のみ管理
MEM-ACC: メモリ資源のみ管理
CPU-MEM-ACC: CPU、メモリ両方管理
2015/10/1
全体ミーティング
18
定義: Accounting Objects
資源の現在の消費量と上限値を保持
usage: 現在の資源消費量
limit: usageの上限
e.g.
2015/10/1
public final class MemAccount {
public long limit;
public long usage=0; public final class CPUAccount {
…
public int limit;
}
public volatile int usage;
…
}
全体ミーティング
19
ThreadLocalの利用
 Accounting Objectへの参照はドメイン内の
thread間で共有
 各threadがThreadLocalとして保持
 静的メソッド getCurrentAccount()で参照
e.g. ドメインA (CPU-MEM-ACC)
MemAccounting
instance
thread1
thread2
CPUAccounting
instance
2015/10/1
全体ミーティング
20
変換アルゴリズム(メモリ)
メモリ使用量をカウント
Allocation直前にコード挿入
上限ckeck & object sizeだけカウンタを増加
Thread Local
な変数memを
get
Limit check
& increment
2015/10/1
void foo() {
MemAccount mem=
MemAccount.getCurrentAccount();
mem.checkLimit(size_of_a);
mem.usage += size_of_a;
Object a = new Object();
}
全体ミーティング
21
ガベコレへの対応
配列以外のオブジェクト
finalizerにカウンタを減少するコードを挿入
配列オブジェクト
弱参照(Weak Reference)を利用
c.f. java.lang.ref.WeakRefefence
解放されたオブジェクトへの弱参照はqueueへ
queueは定期的に空にし、カウンタを減少
2015/10/1
全体ミーティング
22
変換アルゴリズム(CPU)
CPU: 実行命令数をカウント
各基本ブロックの先頭にコード挿入
ブロック内の命令数分カウンタを増加
iconst_0
istore_0
goto 8
+3
iload_0
ldc #1 <Integer 100>
if_icmplt 5
+1
2015/10/1
return
iinc 0 1
+1
+3
CPUAccounting cpu =
CPUAccounting.getCurrentAccount();
cpu.usage += 3;
全体ミーティング
23
高速化~引数を増やす~(1/2)
毎回“getCurrent~()”は遅い!
全メソッドの引数を1 or 2だけ増やす
MemAccount / CPUAccount オブジェクトを引
数で渡す
2015/10/1
全体ミーティング
24
高速化~引数を増やす~(2/2)
Original:
MEM-ACC void a(int x, MemAccount mem) {
b(null, x, cpu);
void a(int x) {
}
b(null, x);
}
CPU-ACC
void a(int x, CPUAccount cpu) {
b(null, x, cpu);
}
CPU-MEM-ACC
void a(int x, MemAccount mem, CPUAccount cpu) {
b(null, x, mem, cpu);
※NO-ACCは変換の必要なし
2015/10/1
}
全体ミーティング
25
Shared classの扱い
Shared Class (java.lang.*, java.io.*, …)
ロード時の変換は不可能
ドメインのtypeを特定できない
“off-line”で書き換え
メソッドのオーバーロード
コードサイズ4倍以上?
2015/10/1
全体ミーティング
26
Shared classの変換例
Original:
void a(int x) {
b(null, x);
}
2015/10/1
void a(int x) {
MemAccount mem = MemAccount.getCurrentAccount();
CPUAccount cpu = CPUAccount.getCurrentAccount();
if (cpu == null)
if (mem == null) a(x, (NoAccount)null);
else a(x, mem);
else
if (mem == null) a(x, cpu);
else a(x, mem, cpu);
}
オ
void a(int x, NoAccount _no) { b(null, x, _no); }
ー
void a(int x, CPUAccount cpu) { b(null, x, cpu); }
バ
void a(int x, MemAccount mem) { b(null, x, mem); } ー
void a(int x, MemAccount mem, CPUAccount cpu) { ロ
ー
b(null, x, mem, cpu);
ド
}
全体ミーティング
27
Limitations
リフレクション
ネイティブコード
ネイティブコード中で使用される資源は管理で
きない
java.lang.Threadが貧弱
2015/10/1
全体ミーティング
28
実験
~CPU資源管理のオーバーヘッド~
2015/10/1
全体ミーティング
29
実験
CPU資源管理によるオーバーヘッドを計測
SpecJVM98ベンチマークを実行
実験環境
Athlon1.2GHz, 256MB RAM, Linux kernel2.4.2
IBM JDK1.3, JIT
2015/10/1
全体ミーティング
30
設定の説明
Ubench-Ujdk
ベンチマーク,shared classの両者とも無変更
Rbench-Ujdk
ベンチマークだけ書き換え
Rbench-Rjdk
ベンチマーク,shared classの両者とも書き換え
2015/10/1
全体ミーティング
31
実験結果 (秒,時間比)
Benchmark
mtrt
jess
compress
db
mpegaudio
jack
javac
GeometricMean
U bench -U jdk
3.783 (1.00)
5.299 (1.00)
11.605 (1.00)
19.775 (1.00)
4.484 (1.00)
4.120 (1.00)
9.400 (1.00)
6.970 (1.00)
R bench -U jdk
4.517 (1.19)
5.842 (1.10)
13.344 (1.15)
20.443 (1.03)
6.316 (1.41)
4.294 (1.04)
10.643 (1.13)
7.989 (1.15)
R bench -R jdk
4.788 (1.27)
6.415 (1.21)
13.449 (1.16)
23.381 (1.18)
6.345 (1.42)
5.033 (1.22)
12.401 (1.32)
8.717 (1.25)
約25%のオーバーヘッド
2015/10/1
全体ミーティング
32
実験結果
25
実行時間(秒)
20
15
Ubench-Ujdk
Rbench-Ujdk
Rbench-Rjdk
10
5
n
et
ric
M
ea
jav
ac
k
jac
au
dio
pe
g
Ge
om
m
co
m
pr
db
es
s
ss
je
m
trt
0
2015/10/1
全体ミーティング
33
関連研究・まとめ
2015/10/1
全体ミーティング
34
関連研究
JRes
CPU, メモリ, ネットワーク資源管理
バイトコード変換+native コード
KaffeOS
独自のJVM (Kaffe)
Alta
Based on Kaffe, nested processes
2015/10/1
全体ミーティング
35
結論
モバイルエージェントに適した資源管理
Pure Java,高いポータビリティー
階層的なドメイン
2015/10/1
全体ミーティング
36
参考文献
“Portable Resource Control in Java The
J-SEAL2 Approach”, Walter Binder, Jarle
G. Hulaas, Alex Villazón, OOPSLA-2001
“Resource Control in J-SEAL2”, Walter
Binder, Jarle G.Hulaas, Alex Villaón,
Technical Report, 2001
2015/10/1
全体ミーティング
37
付録
2015/10/1
全体ミーティング
38
付録: Static Initializer
Static Initializer等,nativeコードから呼び出
されるメソッドはシグニチャを変更不可
cinit() {
…
}
2015/10/1
cinit() {
MemAccount mem = MemAccount.getCurrentAccount();
CPUAccount cpu = CPUAccount.getCurrentAccount();
cinit(mem, cpu);
素直にThreadLocal
}
からmem, cpuの値
をget
cinit(MemAccount mem, CPUAccount cpu) {
…
}
全体ミーティング
39