当我的程序终止时,我是否应该总是在COM指针上调用Release?

时间:2013-12-16 15:56:14

标签: c++ memory-management com iunknown

我知道现代Windows版本会在程序终止后回收先前使用mallocnew等获取的内存,但是COM对象呢?我应该在程序退出时调用obj->Release(),还是系统会为我执行此操作?

我的猜测:取决于。对于进程外COM,我应该总是调用Release(),但对于进程内COM,我认为这无关紧要,因为无论如何COM对象在程序终止后死亡。

3 个答案:

答案 0 :(得分:4)

如果你正处于流程本身,那么你应该因为你可能不知道服务器在哪里而且服务器可能不在proc。如果你在DLL中它会变得更复杂。

在DLL中你应该UNLESS you receive a DLL_PROCESS_DETACH notification,在这种情况下你应该什么都不做,只需让应用程序关闭。这是因为在进程拆除期间调用此通知。因此,在那时清理为时已晚。内核可能已经回收了您调用release的块。

请记住,作为一个DLL编写器,如果进程不合理地退出,你就无法做任何事情,你只能在理性的范围内尽可能地在自己的优雅退出之后进行清理。

一个简单的解决方案是在任何地方使用智能COM指针,ATLWRL具有良好的实现,并使其成为您在大多数情况下不必担心它。即使这些是静态存储的,它们的析构函数也会在进程拆卸或DLL卸载之前调用,因此在安全的情况下安全释放。

所以简短的回答是如果你可以,例如如果可以安全,请务必致电release。然而,有时它不是,你绝对不应该做任何事情。

答案 1 :(得分:3)

根据底层对象的实现,可能会有或可能没有惩罚。对象可能具有超出进程关闭状态的状态。在本地数据库中持久锁定是最容易想到的例子。

考虑到这一点,我说最好不要再打电话给Release。

答案 2 :(得分:2)

  • 进程内COM对象将随进程而死
  • 进程外引用将在超时时释放
    • 设计不良的服务器和客户端可能会保持状态不佳,持有指向对象(通常是代理)的指针,这些指针不再可用,无法看到它们已经死亡。无法摆脱他们
    • 优雅地发布指针
    • 总是一个好主意

如果你没有正确释放COM指针,并且COM活动包括编组,你很可能在CoUninitialze中有例外,它们既烦人又/或最终会向用户显示进程崩溃消息。