第 9 章
本章中的接口和类用于 RMI 的分布式垃圾收集器 (DGC)。
主题:
接口 DGC
Lease 类
ObjID 类
UID 类
VMID 类
9.1 接口 DGC
DGC 抽象用于分布式垃圾收集算法的服务器端。此接口包含两种方法:dirty 和
clean。当远程引用在客户机(客户机由 VMID 表示)端解编时,将调用 dirty
。当客户机中不再存在对远程引用的引用时,将进行相应的清理调用。失败的 d
irty 调用必须预定一次 strong(强)clean 调用,以便保留调用顺序号码,从
而检测以后由分布式垃圾收集器接收的无序调用。
对远程对象的引用将被拥有该引用的客户机租用 (leased) 一段时间。租用期从
接收到 dirty 调用时开始。客户机必须在租用到期前在其所保存的远程引用上再
次调用 dirty,以便进行续租。如果在到期之前不续租,则分布式垃圾收集器就
认为该客户机不再引用远程对象。
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 包含客户机唯一虚拟机标识符 (VMID) 和请求的租用期。垃圾收集器将
为每个本地虚拟机中导出的远程对象保留一个 reference list(引用列表)--
保存引用的客户机列表。如果准予租用,垃圾收集器将把客户机 VMID 添加到 i
ds 中指示的每个远程对象的引用列表中。sequenceNum 用来检测和丢弃后期垃圾
收集器调用的顺序号。每次调用垃圾收集器,顺序号都将增大。
某些客户机不能生成唯一的 VMID。这是因为只有当 VMID 包含 true(真)主机
地址时,才是通用的唯一标识符。由于安全性限制,某些客户机将无法获得该地
址。此种情况下,客户机可以使用空 VMID。分布式垃圾收集器将为客户机指派
VMID。
dirty 调用将返回 Lease 对象,其中包含远程引用所用的 VMID 和准许的租用期
(服务器可以决定授予比客户机请求短的租用期)。客户机必须使用垃圾收集器
所用的 VMID,以便在客户机释放远程对象引用时进行相应的 clean 调用。
客户虚拟机仅需对每个虚拟机中引用的远程引用进行一次初始 dirty 调用(即使
它对同一远程对象进行多次引用)。此外,客户机还必须在租用到期前调用 dir
ty 对远程引用的租用进行续租。当客户机对特定的远程对象再无任何引用时,必
须为与该引用关联的对象 ID 预定一次 clean 调用。
clean 调用将从 ids 指定的远程对象的引用列表中删除 vmid。顺序号用来检测
以后的清理操作。如果参数 strong 为真,则代表 clean 调用是一次失败的 di
rty 调用的结果。此时应记住客户机 vmid 的顺序号。
9.2 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 和租用期的租用。VMID 可以为 null。
getVMID 方法返回与租用相关联的客户机 VMID。
getValue 方法返回租用期。
9.3 ObjID 类
类 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 构造函数的第一种形式将生成唯一的对象标识符。第二个构造函数生成已
知的对象标识符(例如注册服务程序和分布式垃圾收集器所用的标识符),并将
已知的对象号用作参数。第二个构造函数所生成的已知对象 ID 与缺省构造函数
所生成的对象 ID 不冲突;为强制实现这一点,ObjID 的对象号将被设置为构造
函数中提供的“已知”号,同时所有 UID 域均将设置为零。
方法 write 将对象 ID 的表示法编组到输出流中。
方法 read 构造一个对象 ID,其内容将从指定的输入流中读取。
方法 hashCode 将对象号作为 hashcode 返回。
如果 obj 与 ObjID 内容相同,则 equals 方法返回 true。
toString 方法返回一个包含对象 ID 表示法的字符串。仅当对象 ID 来自非本地
地址空间时,地址空间标识符才将含在字符串表示法中。
.4 UID 类
UID 是一种抽象类,用来创建生成它的主机的唯一标识符。它将以地址空间标识
符的形式含在 ObjID 中。UID 由一个在主机上唯一的号码 (int)、时间 (long)
和计数组成 (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 分别
配对。
构造函数的第二种形式将创建一种已知的 UID。已知 ID 有 216 -1 种可能。这
种构造函数所生成的 ID 不会与缺省 UID 构造函数所生成的 ID 冲突。缺省构造
函数生成主机上真正唯一的标识符。
方法 hashCode、equals 和 toString 是为 UID 所定义的。如果两个 UID 的内
容相同,则视为二者等价。
方法 write 将把 UID 写入输出流中。
方法 read 构造一个 UID,其内容将从指定输入流中读取。