C#与COM Interop内存泄漏

时间:2014-07-09 16:24:23

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

您好我有一个项目从VB6迁移到C#并使用许多由其他团队用C ++或VB6编写的Interop COM对象。问题是当我们完成一个应用程序(windows)时,有时它会留在内存中,所以我们必须使用任务管理器将其杀掉。但是同一个程序是Web服装的一部分,可以用作服务。因此,每次用户使用网页时,它都会保留在内存中并保持内存状态。我们以这种方式使用COM对象。

Interop.Sales.SomeClass Obj = new Interop.Sales.SomeClass();

if (obj.prop1.Prom2[1].item[0].prop == something)

...

我的问题是我们是否应该像这样清理根对象

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null; // will it release all underlying objects created when accessing them?

或者必须在访问时清理其在内存中创建的每个子对象?像

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj.prop1.Prom2[1].item[0].prop);
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj.prop1.Prom2[1].item[0]);
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj.prop1.Prom2[1]);
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj.prop1);
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;

我的问题是该项目有超过15000行代码,并且使用相同的方式在许多地方使用COM Interop对象。如果我必须遵循第二种方式,那么这可能是一项非常漫长且有风险的任务。请指导我在COM Interop中发布所有对象的最佳解决方案。

由于

QF

2 个答案:

答案 0 :(得分:1)

我建议你使用:

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

而不是:

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj.prop1);

还需要注意一件事:只需确保在不再需要COM对象时立即释放它。如果您在循环中使用COM对象,请确保在循环结束时释放它们,并且绝不使用 Marshal.FinalReleaseComObject() 它可能会给您一个例外。

希望这会对你有所帮助。

答案 1 :(得分:0)

虽然关于COM的问题更为一般,但在以下链接中使用Excel Interop / COM的问题的答案会告诉您所需的一切。简短的回答是,不,没有捷径。确保您的COM对象尽快正确清理。

Invoking and cleaning up after COM