next up previous contents index
Next: 4.2 Reference and Memory Up: 4.1 Objects and Interfaces Previous: 4.1.2 Querying for Interfaces

4.1.3 Reference Counting

In addition to the basic interface negotiation mechanism provided by standard query method, every COM interface must also export two additional standard methods, addref and release, which are used to control the object's life cycle through reference counting. Whenever a client receives a pointer to a COM interface, e.g., as the result of a call to a method on a different interface, the client is considered to have one reference to the interface. When the client is done using this reference, it must call the release method on that interface so that the object will know when it is no longer in use and can delete itself. If the client needs to copy the reference, e.g., to give it to some third party while still retaining a reference itself, the client must call the addref method on the interface. Eventually, both the client and the third party will call release on their respective pointers to this interface (possibly at different times and in arbitrary order); the object can then be destroyed only when both outstanding references are released.

In COM, only interfaces are reference counted, not the objects themselves. After a client has obtained a reference to a particular interface, it must call the release method on exactly that interface, and not a different interface referring to the same object. This allows object implementations to maintain individual reference counts on each of their interfaces if they choose. Object implementations are also free to maintain only a single reference count for the entire object, in which case the addref and release methods on all the object's interfaces will happen to do the same thing; however, clients must not depend on this behavior.

Cycles

As with all reference counted systems, there is a danger of cycles developing among COM objects and preventing proper garbage collection. For example, if object A holds a reference to object B, and object B holds a reference to object A, then assuming nothing is specifically done to change this situation, the reference counts of both objects will remain nonzero and the objects will effectively ``keep each other alive'' indefinitely even if nothing else in the system still refers to either of those objects. COM does not provide any automatic facility to solve this problem: instead, it must be solved manually by careful design.

One particular technique that can often be used to avoid cycles when two objects both need to maintain pointers to each other is to make one of the objects maintain a reference not to the other object itself, but rather to an inner object which is logically (and possibly physically) part of the main object but is independently reference counted. For example, often a client needs to register a callback object of some kind, such as the network-packet-receive callback object passed to the open method of the oskit_netdev interface. To avoid cycles, the client object should not pass a reference to itself as the callback, but instead should create a separate, independently reference counted callback object which is logically contained in the main client object, and pass a reference to the callback object rather than the main object. This way, the client can keep a reference to the server object, and the server can keep a reference to the callback object, but no cycle will develop and garbage collection works properly.


next up previous contents index
Next: 4.2 Reference and Memory Up: 4.1 Objects and Interfaces Previous: 4.1.2 Querying for Interfaces

University of Utah Flux Research Group