在COM接口中销毁/释放.NET组件

时间:2014-05-21 19:47:46

标签: c# .net memory com

我不习惯COM,但我需要使用C#创建一个.NET组件,将其编译为dll以便在另一个程序套件中使用,所以我将其作为COM对象(注册COM互操作和程序集) COM等可见..)

假设我有我的接口类:

using System.Runtime.InteropServices;

namespace Test
{
 public interface IFoo
 {
  void method1(parameter1);
  void method2 (parameter2);
 }
 [ComVisible(true),ClassInterface(ClassInterfaceType.None)]
 public class myname : IFoo
 {
   FooClass class;
   public myname()//Constructor
   {
   }
   public void method1(parameter1)
   {
     class = new FooClass();
     class.Method1(parameter1);
    }
 }
}

在此之后我编译它并使用regasm在另一台计算机上注册dll。我运行它,但是这个应用程序消耗大量内存并且从不释放自己,有没有人知道释放它/销毁它的方法?

问题是如何释放memry用法?提前谢谢

1 个答案:

答案 0 :(得分:1)

通过COM调用.NET,内存泄漏通常发生在COM Callable Wrapper层。

当COM客户端调用.NET对象时,公共语言运行库会为该对象创建托管对象和COM可调用包装器(CCW)。无法直接引用.NET对象,COM客户端使用CCW作为托管对象的代理。

CCW以传统的COM方式进行引用计数。当CCW上的引用计数达到零时,包装器将在托管对象上释放其引用。在下一个垃圾收集周期中收集没有剩余引用的托管对象。因此,如果对象的引用计数未减少到0,那么就会出现泄漏

最近我也处理相同的案例,根据我的经验,你应该:

  1. 检查您是否在本机代码中使用COM智能指针类型。使用#import xxx.tlb时,编译器会创建如下代码:

    _COM_SMARTPTR_TYPEDEF(IFoo,__ uuidof(IFoo));

    当你在C ++代码中使用IFoo接口时,你应该使用IFooPtr,这是一个COM智能指针类型,当变量超出范围时将调用Release()函数。

  2. SAFEARRAY的用法。当您从C#返回一个数组时,它将作为SAFEARRAY *类型返回给C ++,您必须在该安全数组上调用SafeArrayDestory()来释放内存。

  3. 我使用的工具是DebugDiag。它来自微软,免费且功能强大。