内存泄漏是因为我的dll触发了其他一些dll。功能

时间:2014-08-05 23:32:20

标签: c# memory-leaks com garbage-collection arcgis

在我的应用程序中,我使用了很多com对象。

我正在发布所有com对象,我声明但是我的应用程序正在触发其他一些应用程序,它也使用了一些com对象和该应用程序创建内存泄漏。

触发部件从循环激活,因此我有机会在每次迭代中释放所有com对象。 我想知道是否有任何方法可以释放其他应用程序使用的所有com对象。

我使用以下代码来发布com对象。

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

我理解GC维护一个表,该表保存与所有引用对象相关的所有条目,但是如果某个其他应用程序在我的应用程序空间内创建堆,GC将如何表现。

1 个答案:

答案 0 :(得分:2)

您手动实施与FinalReleaseComObject相同的内容。如果你要这样做,我认为你会想要继续使用内置的FinalReleaseComObject方法,因为从语义上来说它代表了你在循环中正在做的事情,因为它是一个框架的内置部分,如果它出现问题,可能会从微软那里获得错误修复的爱,并且因为使用它会遵守DRY

来自Microsoft FinalReleaseComObject上的MSDN页面(重点是我的):

  

当COM对象上的引用计数变为0时,COM对象通常被释放,虽然这取决于COM对象的实现并且超出了运行时的控制。但是,RCW仍然存在,等待垃圾收集。

然而this article on CodeProject,以及Microsoft的模式和实践,建议您不要使用FinalReleaseComObject,而是要确保调用ReleaseComObject以与实例化对象相反的顺序。

换句话说,只有一个ReleaseComObject与每个作业配对。明智地使用try / finally可能是一个好主意,以保证每次分配都会发布。

执行此操作,当您“展开”COM对象图时,每个COM对象的RCW引用计数自然会降至0,如果您的COM对象不是不正常,则应该将其释放。

注意CodeProject文章中关于确保释放从方法调用返回的COM对象的内容。如果您只是忽略这些返回值,则并不意味着它们不存在。你可以参考他们等待多代垃圾收集。因此,您需要确保在这些内容上调用ReleaseComObject

Marshal.ReleaseComObject( myCom.ProcessError (5) ); //Release returned object
Marshal.ReleaseComObject( myCom );

使用FinalReleaseComObject似乎有点像投掷冰雹玛丽并祈祷最好。这有点像你在说“嘿,当我旋转这个物体时,我并没有真正注意,但请尽量让它为我消失。”