c#与COM互操作内存泄漏

本文关键字:内存 泄漏 互操作 COM | 更新日期: 2023-09-27 18:12:16

嗨,我有一个从VB6迁移到c#的项目,使用了其他团队用c++或VB6编写的许多互操作COM对象。问题是当我们完成一个应用程序(windows)时,有时它会留在内存中,所以我们必须使用任务管理器杀死它。但同样的程序是web suit的一部分,可以作为一种服务来使用。因此,每次用户使用这个网页时,它都会留在内存中并保持内存。我们以这种方式使用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互操作对象在许多地方使用相同的方式。如果我必须遵循第二种方式,那么这可能是一个非常漫长和危险的任务。请指导我在COM互操作中释放所有对象的最佳解决方案。

感谢

c#与COM互操作内存泄漏

我建议您使用:

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

代替:

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

还有一件事需要注意:只要确保在不再需要COM对象时释放它们即可。如果你在循环中使用COM对象,确保在循环结束时释放它们,并且永远不要使用 Marshal.FinalReleaseComObject() ,它可能会给你一个异常。

虽然你的问题是关于COM的更一般的问题,关于使用Excel Interop/COM在以下链接的问题的答案告诉你你需要的一切。简短的回答是,没有捷径。确保你的COM对象被正确地、尽快地清理干净。

调用和清理COM