通过引用计数管理对象生存期

在传统对象系统中,对象的生命周期(即对象创建和删除相关问题)由语言(或语言运行时)隐式处理或由应用程序程序员显式处理。

在由重用组件组成的不断完善、结构分散的系统中,任何客户端,甚至任何程序员都不再“清楚”如何处理组件的生存期。 对于具有适当安全权限的客户端,通过简单请求创建对象仍然相对比较容易,但对象删除则完全是另一回事。 不一定清楚对象何时不再需要并应删除。 (熟悉垃圾回收编程环境的读者(如 Java)可能不同意这一说法;但是,Java 对象不会跨越计算机甚至进程边界,因此垃圾回收仅限于单进程空间中的对象。此外,Java 强制使用单个编程语言。)即使原始客户端用完对象,也不能简单地将其关闭,因为其他一些客户端可能仍在引用该对象。

确保不再需要对象的方法之一是完全依赖基础信道,以在与跨进程或跨通道对象的所有连接都消失时通知系统。 但是,出于多种原因,使用此方法的方案不可接受。 一个问题是,可能需要在跨进程/跨网络编程模型和单进程编程模型之间做出重大改变。 在跨进程/跨网络编程模型中,通信系统将提供对象生存期管理所需的挂钩,而在单进程编程模型中,对象直接连接,无需任何干预信道。 另一个问题是,此方案还可能导致系统提供的软件层影响进程内的组件性能。 此外,基于显式监视的机制不会扩展到数千或数百万个对象。

COM 为这组问题提供一种可扩展的分布式方法。 客户端告诉对象何时使用以及何时用完,当不再需要时,对象会自行删除。 此方法要求所有对象自行进行引用计数。 Java 等编程语言本身具有自己的生存期管理方案(如垃圾回收),可以使用 COM 的引用计数在内部实现和使用 COM 对象,从而程序员无需对其进行处理。

正如应用程序必须释放已分配的内存,一旦该内存不再使用,对象的客户端便负责释放对不再需要的对象的引用。 在面向对象的系统中,客户端只能通过向对象提供释放自身的指令来执行此操作。

当对象不再使用时,必须解除分配。 难在确定何时适合解除分配对象。 使用自动变量(在堆栈上分配的变量)可以轻松做到,对象不能在声明对象的块之外使用,因此编译器可在到达块的末尾时解除分配对象。 对于动态分配的 COM 对象,由对象的客户端决定何时不再需要使用对象,尤其是可能同时由多个客户端使用的本地或远程对象。 对象必须等待,直到所有客户端都用完,然后释放对象。 由于 COM 对象通过接口指针操作,并且可由不同进程或其他计算机上的对象使用,因此系统无法跟踪对象的客户端。

COM 确定何时适合解除分配对象的方法是手动引用计数。 每个对象都维护一个引用计数,用于跟踪所连接的客户端数,即任何客户端中的任何接口存在的指针数。

有关详情,请参阅以下主题:

使用和实现 IUnknown