It is important to be clear about the meaning of object existence which, as far as the Ice run time is concerned, is defined only within the context of a particular operation invocation. It is also important to be clear about the distinction between proxies, servants, and Ice objects, which have independent life cycles.
While object creation is usually simple, object destruction requires a great deal of attention, particularly for threaded servers: the interactions among life cycle operations and ordinary operations can be complex and require careful consideration with respect to locks.
Frequently, implementing object destruction with reaping instead of callbacks leads to simpler and more maintainable code and eliminates hidden dependencies that can cause deadlock.
Ultimately, the semantics of object existence are supplied by the application code. Depending on how an application is structured, object identities may need to be globally unique; alternatively, if the life times of proxies that use the same identity for different objects cannot overlap, object identities can be safely re-used. It is important to be aware of the respective semantics in order to create correct applications.
If interactions between clients and server are stateful, the server must take care to reclaim state to protect itself against resource exhaustion if clients fail to destroy that state.