当我的程序终止时,我应该总是在COM指针上调用Release吗?
我知道,现代Windows版本收回先前与malloc
,new
之类的,节目结束后,但对于COM对象获得的记忆?我应该在程序退出时致电obj->Release()
,还是系统会为我做这件事?当我的程序终止时,我应该总是在COM指针上调用Release吗?
我猜它:这取决于。对于进程外COM,我应该总是调用Release()
,但是对于进程内COM,我认为这并不重要,因为COM对象无论如何都会在程序终止后死掉。
如果你在这个过程本身是则是你应该为你可能不知道服务器,服务器可能会出PROC的。如果你在一个DLL中,它变得更加复杂。
在DLL你应该UNLESS you receive a DLL_PROCESS_DETACH
notification,在这种情况下,你应该什么都不做,只是让应用程序关闭。这是因为这个通知在进程拆卸期间被调用。因此,在这一点上清理已经太迟了。内核可能已经回收了您调用release
的块。
记住作为一个DLL作家有什么可以做,如果处理非正常退出,只能尽你所能的原因后自己清理在正常退出之内。
一个简单的解决方案是在任何地方使用智能COM三分球,ATL和WRL有一个很好的工作,使它所以你不必担心它的大部分实现。即使这些静态存储,它们的析构函数也会在进程拆卸或DLL卸载之前调用,从而在安全的情况下安全释放它们。
那么简单的答案是如果可以例如如果安全的话,您应该始终致电release
。然而,有些时候不是,你绝对不应该做任何事情。
其实,这是一个DLL。你真的说我不应该在'DLL_PROCESS_DETACH'中调用'Release()'吗? 'DLL_THREAD_DETACH'是否一样?据柜台似乎我期待什么(也许原因在过程结束该DLL卸载不排序?) – Abel
@Abel我把从[Raymond Chen的博客(http://blogs.msdn.com/b/oldnewthing/存档/ 2012/01/05/10253268.aspx)。主要是因为该进程退出,可以假设,在这一点上的任何行动可能会导致不确定的行为 – Mgetz
去为你的答案在这里,为您提供最全面的信息,而在其他的答案,也就是很多宝贵的信息。谢谢大家! – Abel
根据底层对象的实现,可能会或可能不会有惩罚。该对象可能具有超出流程关闭的状态。想到本地数据库中的永久锁定是最简单的例子。
考虑到这一点,我说为了以防万一,最好打电话给Release。
是,或者是一个记录的COM对象,可能需要刷新当前缓冲区,否则它不会写入最新的日志语句。这种 - 与上面的@Mgetz中的'DLL_PROCESS_DETACH'中的“什么也不做”相矛盾。如果只是需要释放的内存,这是一回事,但是当释放计数变为零时,某些COM对象可能仍然需要执行某些操作。 – Abel
- 过程中的COM对象将与过程
- 消亡的进程参考在超时发布
- 设计不当的服务器和客户端可能会保持在恶劣的国有控股对象的指针(通常代理),不再可用,无法看到他们已经死了。暂时无法摆脱他们
- 它总是以释放指针优雅
如果不释放COM指针正常,而COM活动包括封送一个好主意,你很可能在CoUninitialze
中有例外,它们都很烦人,并且/或者最终会向用户显示进程崩溃消息。
实际上没有考虑编组和CoUnitialize,但它是有道理的。所以,这也是对来自“无为”的说法[Raymond Chen的博客(http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx)当'DLL_PROCESS_DETACH'来(如果COM对象在DLL中)。 – Abel
@Abel其实不是的话,你应该叫释放之前'DLL_PROCESS_DETACH'如果你调用它当墙壁下来你应该会坏事情发生。请记住,在进程退出之前调用'CoUninitialize'。 – Mgetz
如果没有进行任何进程外COM,那么使用SetErrorMode来抑制消息并立即死亡可能是一个好主意。好吧,也许不是那么好,但至少有理由尽快退出。无论如何,我总是喜欢释放指针。毕竟,一些COM对象可能希望将它的持久状态保存在上一个'Release'中。 –
尝试优雅地关闭您的程序:即用Release()平衡所有的AddRef()。 – Bathsheba
尽管可能不需要,但清理后总是一个好主意。 –
@ Bathsheba/@ Joachim:我会这么做的,但那并不能真正回答这个问题。如果我有不平衡的COM调用,即没有发布,会发生什么?我可能是懒惰的,但如果对象必须在程序的整个生命周期中坚持下去,它真的很重要吗? – Abel