dirty と clean という2つのメソッドを持っています。
dirty コールはリモート参照がクライアントにより整理されていないときに発生します。(クライアントは VMID により示されます)。
対応する clean コールはクライアント側にそれ以上のリモート参照が存在しなくなったときに発生します。
dirty コールが失敗した場合には、強い clean コールをスケジューリングしてコールの順序番号を保持し、将来分散ガベージコレクタが番号の食い違った命令を受けてもそれを検出できるようにしなければなりません。
リモートオブジェクトへの参照はしばらくの間、参照を保持しているクライアントによって lease されます。
lease される期間は dirty コールが受け付けられた時点をスタートとします。自分が保持するリモート参照の lease 期間が切れないように追加の dirty コールを発行して lease を更新するのはクライアント側の責任です。
もしクライアントが lease が切れる前に更新するのを怠ると、分配ガベージコレクタは、そのリモートオブジェクトはもはやクライアントから参照されていないと判断します。
package java.rmi.dgc;
import java.rmi.server.ObjID;
public interface DGC extends java.rmi.Remote {
Lease dirty(ObjID[] ids, long sequenceNum, Lease lease)
throws java.rmi.RemoteException;
void clean(ObjID[] ids, long seqNum, VMID vmid, boolean strong)
throws java.rmi.RemoteException;
}
dirtyメソッドは、配列引数 ids に含まれるオブジェクト識別子に関連付けられたリモートオブジェクト参照の lease を要求します。
Lease はクライアントの一意の仮想マシン識別子 (VMID) と要求された lease 期間を持っています。ローカルな仮想マシンでエクスポートされるそれぞれのリモートオブジェクトについて、ガベージコレクタは参照リスト (reference list) (ガベージコレクタへの参照をもつクライアントのリスト)を保持しています。
もし lease が許可されるとガベージコレクタはクライアントの VMID をそれぞれの識別子で表されるリモートオブジェクトの参照リストに追加します。
sequenceNum パラメーターはガベージコレクタへの遅れたコールを検出して除外するために使用するシーケンス番号です。
シーケンス番号はガベージコレクタへのコールが発生するたびに常に増加してゆきます。
クライアントの中には一意の VMID を作れないものもあります。
この理由は VMID が true ホストアドレスを含んでいる場合にのみ全体を通して一意な値を取り得るのにたいして、クライアントの中にはセキュリティ上の制限によりアドレスを取得できないことがあるからです。
この場合クライアントは VMID として null を使うことができ、分散ガベージコレクタはそのクライアントに対して VMID を割り付けます。
dirty コールは Lease オブジェクトを返し、そのオブジェクトには使用されている VMID と、そのリモート参照に許可されている lease 期間が含まれています(サーバはクライアントが要求するよりも短い lease 期間を許可する権限があります)。
クライアントは、自分がリモートオブジェクト参照を取り下げたときに対応する clean コールが実行されるために、ガベージコレクタが使用する VMID を使わなければなりません。
クライアントの仮想マシンはそのマシン内で参照されている各リモート参照に対して最初に一回だけ dirty を行う必要があります(たとえ同一のリモートオブジェクトに対して複数の参照がなされていたとしても一回だけです)。
クライアントはまた、リモート参照への lease 期間が消滅する前に、lease 更新のために dirty コールを実行する必要があります。
クライアントがもはや特定のリモートオブジェクトへの参照を持たない状態になると、その参照に関連したオブジェクト ID のための clean コールをスケジューリングしなければなりません。
clean コールは各リモートオブジェクトの参照リストから id で識別される VMID を削除します。
シーケンス番号により遅れた clean コールを検出することができます。引数 strong が true の場合はその clean コールは失敗した dirty コールの結果生じたものです。したがってこの場合にはクライアントの vmid に対応するシーケンス番号は記憶しておかなければなりません。
Lease オブジェクトはリモートオブジェクト参照への lease 要求と許可を与えるために使われます。
package java.rmi.dgc;
public final class Lease implements java.io.Serializable {
public Lease(VMID id, long duration);
public VMID getVMID();
public long getValue();
}
Lease コンストラクタは特定の VMID の lease期間で lease を生成します。
VMID は null である場合もあります。
getVMID メソッドはその lease に関係付けられたクライアントの VMID を返します。
getValue メソッドは lease 期間を返します。
ObjID クラスは時間が経過したとしても仮想マシン内でリモートオブジェクトを一意に同定するために使われます。
それぞれの識別子にはオブジェクト番号と特定のホストで一意に決まるアドレス空間識別子が書かれています。
リモートオブジェクトにはそれがエクスポートされたときにオブジェクト識別子が割り付けられます。
ObjID はオブジェクト番号 (long) とアドレス空間への一意の識別子 (UID) から構成されます。
package java.rmi.server;
public final class ObjID implements java.io.Serializable {
public ObjID ();
public ObjID (int num);
public void write(ObjectOutput out) throws java.io.IOException;
public static ObjID read(ObjectInput in)
throws java.io.IOException;
public int hashCode()
public boolean equals(Object obj)
public String toString()
}
ObjID コンストラクタの最初の形式は一意のオブジェクト識別子を作成します。
コンストラクタの2つ目の形式は(レジストリや分散ガベージコレクタが使用する)well-known オブジェクト識別子を作成して well-known オブジェクト番号を引数とします。
第二のコンストラクタで作成された well-known オブジェクト ID が他のデフォルトコンストラクタで作成された ID と衝突することは許されません。これを確実に行うために、 ObjID のオブジェクト番号はコンストラクタが提供する "well-known" 番号を使用して、全てのUID フィールドはゼロに設定されます
write メソッドはオブジェクト ID の表現を一体化して出力ストリームに乗せます。
read メソッドは特定の入力ストリームから得られた内容からオブジェクト ID を構築します。
hashCodeメソッドはオブジェクト番号を hashcode として返します。
equals メソッドはもし obj が同じ内容の ObjID であったときに true を返します。
toString メソッドはオブジェクト ID の表現を含んだ文字列を返します。文字列表現の中にアドレス空間識別子が含まれるのはオブジェクト ID が非ローカルアドレス空間から来たものであるときだけです。
UID クラスはそれが生成されるホスト上で一意に定まる識別子を作成するための抽象化です。
UID は ObjID にアドレス空間識別子として含まれます。
UID はホスト上で一意の数 (int)、時間(long)、そしてカウント (a short) から構成されます。
package java.rmi.server;
public final class UID implements java.io.Serializable {
public UID();
public UID(short num);
public int hashCode();
public boolean equals(Object obj);
public String toString();
public void write(DataOutput out) throws java.io.IOException;
public static UID read(DataInput in) throws java.io.IOException;
}
UID は次の条件下で一意に定まります: a) マシンはリブートするのに一秒以上を要する、そして b) マシンのクロックが決して時間をさかのぼって再設定されない。 グローバルに一意的な UID を作り出すには、単に UID と InetAddress を組み合わせます。
第二の形式のコンストラクタは well-known UID を作り出します。 全部で 216 -1 通りの well-known ID を作ることができます。 このコンストラクタが作る ID は他のデフォルト UID コンストラクタが作るホスト上で真に単一の識別子と衝突することが許されません。
hashCode メソッド、equals メソッド、そして toString メソッドが UID のために定義されています。
2つの UID は内容が完全に一致するとき等しいといわれます。
write メソッドは UID を出力ストリームに書きます。
read メソッドは特定の入力ストリームから読み込まれた内容から UID を作ります。
VMID クラスは全ての Java 仮想マシン上で唯一無二の識別子を与えます。
VMID は UID とホストアドレスを含みます。
VMID はクライアントの仮想マシンを識別するために使います。
package java.rmi.dgc;
public final class VMID implements java.io.Serializable {
public VMID();
public static boolean isUnique();
public int hashCode();
public boolean equals(Object obj);
public String toString();
}
VMID のデフォルトコンストラクタは次の条件下で、全ての Java 仮想マシン上でグローバルに一意な識別子を作成します。
java.rmi.server.UID クラスのオブジェクトに関する一意性の条件を満たしていること、および UID オブジェクトの生存期間中一意で一定のホストアドレスが得られること。
VMID は自分がその上で生成されたマシンのホストアドレスを保持しています。
セキュリティ上の制限により、真のホストアドレスを得られない場合があり得ます(例えばループバックホストはセキュリティ上制限された使い方をされます)。
isUnique メソッドは、この仮想マシン上で作成された VMID が実際すべてのマシン中で一意であることをチェックするときに呼び出されます。
isUnique メソッドは有効なホスト名(ループバックホスト以外で)を決定できるときに true を返し、そうでないときは false を返します。
hashCode メソッド、 equals メソッド、そして toString メソッドは VMID のために定義されます。
2つの VMID は内容が一致するときに等しいと呼ばれます。