我知道现代Windows版本在程序终止后会回收以前用malloc
、new
等获取的内存,但COM对象呢?我应该在程序退出时调用他们的obj->Release()
吗?还是系统会为我这样做?
我猜:这取决于。对于进程外COM,我可能应该始终调用Release()
,但对于进程内COM,我认为这真的无关紧要,因为无论如何,COM对象都会在程序终止后死亡。
如果你在进程本身,那么是的,你应该知道,因为你可能不知道服务器在哪里,服务器可能不在进程中。如果你在DLL中,它会变得更加复杂。
在DLL中,除非你收到DLL_PROCESS_DETACH
通知,否则你应该什么都不做,只让应用程序关闭。这是因为此通知是在进程拆卸期间调用的。因此,现在清理已经太迟了。内核可能已经回收了您在.上调用release
的块
请记住,作为一名DLL编写器,如果进程不体面地退出,你将无能为力,你只能在合理的范围内做你能做的事情,在自己优雅地退出后进行清理。
一个简单的解决方案是在任何地方使用智能COM指针,ATL和WRL的实现都能很好地工作,因此您在很大程度上不必担心它。即使这些是静态存储的,它们的析构函数也会在进程拆卸或DLL卸载之前被调用,从而在安全的时候安全地释放
因此,简短的答案是如果可以,例如,如果安全的话,你应该始终致电release
。然而,有时情况并非如此,你绝对不应该做任何事情。
根据底层对象的实现,可能会有也可能不会有惩罚。对象的状态可能会持续到进程关闭之后。本地数据库中的持久锁是最容易想到的例子。
考虑到这一点,我认为最好打电话给Release以防万一。
- 进程内COM对象将随进程一起消亡
- 进程外引用将在超时时释放
- 设计糟糕的服务器和客户端可能会保持糟糕的状态,持有指向对象(通常是代理)的指针,这些对象不再可用,无法看到它们已经死了。无法摆脱他们
- 优雅地释放指针总是个好主意
如果您没有正确释放COM指针,并且COM活动包括封送处理,那么CoUninitialze
中很可能会出现异常,这些异常既令人讨厌,又可能最终向用户显示进程崩溃消息。