杀死 COM 服务器而不释放 .net 中的 com 对象有什么危害吗?
各位 - 我正在 .net 中创建许多 COM 服务器(我正在启动许多 EXE),通过 COM -interop 与 COM 通信,在服务器中使用大量 COM 对象等。如果我终止该进程,有什么危害吗?不释放我通过 Marshal.FinalReleaseComObject() 使用的所有 COM 对象有什么不好吗?随着时间的推移我会出现内存泄漏吗?
Folks - I'm creating many COM servers (I'm launching numerous EXEs) in .net, talking to COM via COM -interop, using numerous COM objects in the server, etc. If I kill the process, is there any harm? Is there anything bad about NOT releasing all the COM objects I've used via Marshal.FinalReleaseComObject()? Will I have a memory leak over time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我假设您正在谈论进程外 COM 服务器,尽管它们远不如进程内服务器常见。杀死客户端应用程序是不好的,服务器将永远不会收到释放调用,客户端分配的任何对象的资源将继续使用,直到 EXE 终止。终止服务器应用程序将使客户端应用程序因 RPC 错误而失败,不会泄漏任何内容。
不使用 Marshal.FinalReleaseComObject() 并没有什么不好,COM 对象引用计数由 RCW(运行时可调用包装器)管理。与 .NET 编程中的任何其他对象一样,它是一个托管对象,由垃圾收集器负责处理。当终结器运行时,引用计数会递减。当这种情况发生时,是无法预测的。
使用 Final/ReleaseComObject() 可以使其变得可预测,但您必须在创建的每个对象上调用它。这可能很困难,例如,当您使用索引器时,您创建的索引并不总是显而易见的。这也是危险的,错误的调用时机或未正确跟踪对对象的所有引用会导致臭名昭著的“无法使用已与其底层 RCW 分离的 COM 对象”异常。精彩的战争故事可在此处获取。
I'll assume you are talking about out-of-process COM servers although they are far less common than in-process servers. Killing the client app is bad, the server will never get the release calls, the resources for any objects that the client allocated will stay in use until the EXE is terminated. Killing the server app is going to make the client app fail with RPC errors, nothing is leaked.
There's nothing bad about not using Marshal.FinalReleaseComObject(), COM object reference counts are managed by the RCW (runtime callable wrapper). It is a managed object like any other in .NET programming, the garbage collector takes care of it. The reference count is decremented when the finalizer runs. It is unpredictable when that happens.
Using Final/ReleaseComObject() can make it predictable but you have to call it on every object you create. Which can be difficult, it isn't always obvious that you created one when you use the indexer for example. It is also dangerous, mis-timing the call or not properly tracking all references to the object causes the infamous "COM object that has been separated from its underlying RCW cannot be used" exception. A good war story is available here.