繁体   English   中英

使用COM和C#的多线程应用程序中的内存泄漏

[英]Memory leaks in a multi-threaded application using COM & C#

我编写了一个多线程非托管应用程序,该应用程序在其工作线程中使用COM对象。 一切顺利,直到我开始使用导出为COM的.NET对象来完成工作。

试着玩弄代码并注释掉.NET对象功能的某些部分,我设法将其固定为.NET对象中COM对象的用法。 总结一下:

  1. 我的程序启动了几个工作线程。
  2. 每个工作线程都会初始化一个基于.NET的COM对象来完成工作。
  3. 基于.NET的COM对象在内部使用非托管COM对象。

令我惊讶的是,直到OutOfMemory异常开始出现之前,应用程序的内存消耗开始稳定增长。

这是我的.NET实现:

void DoSomeWork()
{
    IComObject O = new ComObjectClass();
    try
    {
        // do something
    }
    finally
    {
        Marshal.ReleaseComObject(O);
    }

}

如果我注释掉此功能,内存泄漏将消失。 如果我在其中调用GC.Collect(),则仍然会发生内存泄漏。

关于可能发生的事情有什么想法吗?

编辑:基于注释和答案的更多信息:

  1. 创建的所有线程都在MTA中运行。
  2. 所有COM对象都实现IMarshal并使用自由线程封送处理程序。
  3. 做什么是无关紧要的-即使是int i = 0; i ++; 产生泄漏。
  4. ComObjetClass记录的对象是旧的并且经过测试。 这并不意味着它没有问题,但并不刺眼。
  5. 我尝试通过C#程序在主线程上以及另一个创建的线程上反复创建COM对象。 在这两种情况下,内存泄漏都消失了。 从非托管代码到托管代码的交叉似乎又是至关重要的。 删除其中的任何部分都会导致问题消失。

可能是您的COM包装对象需要切换到STA线程才能完成。 如果您的STA不发送消息,则将永远不会发生,因此将不会调用finalize,这反过来会导致内存泄漏。

此KB中有更多信息。

您好建议您使用以下代码。

     if (feature != null) 
        { 
            while (Marshal.ReleaseComObject(feature) > 0) 
            { }
            feature=null;
        }

如果您使用com对象作为引用类型。 恩。 光标。 如果您只是在做Marshal.ReleaseComObject(O);

比仅释放一个引用要多,其余的引用将保留在内存中,因此最好释放所有引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM