对象的生命周期

本主题介绍对象的“生命周期”,即对象管理器如何引用和跟踪对象。 本主题还介绍如何使对象成为临时对象或永久对象。

对象引用计数

对象管理器维护对对象的引用数的计数。 创建对象时,对象管理器会将对象的引用计数设置为一个。 该计数器下降到零后,将释放该对象。

驱动程序必须确保对象管理器对其操作的任何对象具有准确的引用计数。 过早释放的对象可能会导致系统崩溃。 引用计数错误地高的对象将永远不会被释放。

可以通过句柄或指针引用对象。 除了引用计数之外,对象管理器还维护对对象的打开句柄数量的计数。 每个打开句柄的例程都会使对象引用计数和对象句柄计数各增加一个。 对此类例程的每个调用都必须与 对 ZwClose 的相应调用匹配。 有关详细信息,请参阅 对象句柄

在内核模式下,可以通过指向对象的指针引用对象。 返回指向对象的指针(如 IoGetAttachedDeviceReference)的例程会使引用计数加一。 一旦驱动程序完成使用指针,它必须调用 ObDereferenceObject ,以便将引用计数减少一个。

以下例程均会将某个对象的引用计数增加一:

ExCreateCallback

IoGetAttachedDeviceReference

IoGetDeviceObjectPointer

IoWMIOpenBlock

ObReferenceObject

ObReferenceObjectByHandle

ObReferenceObjectByPointer

对上述任一例程进行的每个调用都必须与对 ObDereferenceObject 的相应调用匹配。

提供了 ObReferenceObjectObReferenceObjectByPointer 例程,以便驱动程序可以逐个增加已知对象指针的引用计数。 ObReferenceObject 只会增加引用计数。 ObReferenceObjectByPointer 在增加引用计数之前执行访问检查。

ObReferenceObjectByHandle 例程接收对象句柄,并提供指向基础对象的指针。 它还会将引用计数增加一个。

临时对象和永久对象

大多数对象都是 临时的;只要正在使用它们,它们就会存在,然后由对象管理器释放。 可以创建 永久对象。 如果对象是永久性的,则对象管理器本身将保留对对象的引用。 因此,对象的引用计数仍然大于零,因此当对象不再使用时,仍然不会被释放。

临时对象仅当其句柄计数为非零时才能按名称访问。 句柄计数递减为零后,将从对象管理器的命名空间中删除该对象的名称。 只要这些对象的引用计数仍大于零,就可以通过指针访问。 只要永久对象存在,就可以按名称进行访问。

通过在对象的 OBJECT_ATTRIBUTES 结构中指定OBJ_PERMANENT属性,可以在创建对象时永久创建对象。 有关详细信息,请参阅 InitializeObjectAttributes

若要临时创建永久对象,请使用 ZwMakeTemporaryObject 例程。 此例程会导致对象在不再使用后自动删除。 (如果对象没有打开的句柄,则会立即从对象管理器的命名空间中删除该对象的名称。对象本身将一直保留,直到引用计数降至零。