c# - 在 C# 中使用大量 COM 对象的内存使用过多

标签 c# memory-leaks memory-management com-interop

我有一个最初用 VB6 编写的应用程序,我使用工具将其转换为 C#,从功能的角度来看,它取得了相当大的成功。它使用大量中小型 COM (C++) 对象处理大量消息。

我注意到在旧的 VB6 应用程序中运行的特定测试使用不到 40M 的内存运行,在 C# 应用程序中需要将近 900M。如果我将 GC.Collect() 放在 C# 应用程序最内部的消息处理循环中,它使用与 VB6 应用程序相同或更少的内存,尽管它真的非常慢。这让我相信绝对意义上的“泄漏”是不存在的。

然后我通过 AQTime 内存分析器运行 C# 应用程序,它报告说堆上存在过多的 COM/C++ 对象。我假设这是因为围绕 COM 对象的运行时可调用包装器非常小,并且从不(或很少)触发 C# 中的收集,即使它们引用的 COM 对象大得多。我想我可以通过在 C# 应用程序中的 COM 对象周围添加显式 Marshal.ReleaseComObject() 调用来解决这个问题。我去了很多 COM 对象的生命周期很容易确定的地方并这样做了。我注意到内存使用量只有非常轻微的减少。

我想知道为什么我在这方面没有取得更好的成功。查看 Marshal 类中的静态方法,我看到一些让我相信我可能在处理 COM 引用时遗漏了一些微妙之处,或者我认为当 RCW 的引用计数达到零时它们会立即被销毁的假设是不正确的.

对于我可以尝试的其他方法或我可能忽略或误解的其他事情,我将不胜感激。

最佳答案

抱歉提供了链接而不是一个好的概要,但我自己从来没有遇到过这个问题,因为我在一个长期存在的场景中处理过 IE 和 mshtml。

文章指出:

When using a COM object from a .NET-based application, there are two objects involved: the RCW and the COM object (or objects). Garbage collection is only aware of the size of the RCW (which can be small), not of the COM object (which may be large). Therefore, while the .NET-based application might release the RCW, garbage collection may not reclaim the RCW even as memory runs out. As long as the RCW stays in memory, the COM object that it manages stays in memory also.

There are two mechanisms that ensure that COM objects are released from memory: the AppDomain object and the ReleaseComObject method. Using an AppDomain provides the simplest solution to managing COM objects but has performance costs and can expose a security risk. Using ReleaseComObject avoids those costs but requires more careful planning and coding.

关于c# - 在 C# 中使用大量 COM 对象的内存使用过多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5306666/

相关文章:

c# - 如何为动态添加的按钮创建方法。 ASP.NET C#

c# - 如何创建 Linq 表达式来创建最多 100 个对象的组

C++ 内存泄漏检测发生在错误的时间? (C 数组)

java - Java 中的清除 protected 双向链表

objective-c - 如何在ARC下自动释放未返回的对象

c# - 迭代 HashSet 时更改项的值

c# - Visual Studio Performance Profiler "Force GC"按钮实际上在做什么?

linux - 分析网络应用程序中的资源泄漏(套接字处理程序等)

delphi - 如何获取实例内存泄漏的自定义结构体的名称?

Objective-C:在自动发布的 NSDictionary 中保留 NSDictionary