Consumer of COM interface has no control over destruction of COM class/object. Consumer's responsibility is to accurately call IUnknown::Release
once an interface pointer needs to be released. While returned zero is typically an indication of "last release, and destruction" of the object, this value is informational and does not guarantee object destruction. It is COM object responsibility to do proper freeing when there are no external references to the object exist.
The rest of destruction is the responsibility of COM object implementation. Once it detects it was released by everyone holding references, it typically does self-destruction, in simplest scenario. However, it does not have to be this way exactly. The object might have some background activity to extend lifetime, there are singletons and cached objects where there is certain logic to keep object alive etc.
Hence, troubleshooting destruction splits into proper interface reference counting (AddRef/Release) and checking COM server to properly shutdown activity in absence of consumers (including freeing memory and resources).