我正在开发一个 .NET 应用程序,用于处理通过 ESRI 自己的 .NET 互操作程序集使用 ESRI 的 ArcObjects COM 库的地理数据。
在生产环境中运行时,由于达到每个进程 2GB 的内存限制,该进程可能会在某些操作期间崩溃。(ArcObjects 是一个 32 位库。)这是因为某些处理步骤可以创建许多临时 ArcObjects 几何对象。FinalReleaseComObject
尽管使用和关联的辅助方法手动释放这些对象,但它会泄漏内存并最终耗尽内存。但是,我可以通过调用强制GC释放内存WaitForPendingFinalizers
,并定期调用它GC.Collect
并FinalReleaseComObject
控制内存使用。否则,许多对象会保留在内存中,直到进程退出(正常或异常)。
第一个问题:为什么 ArcObjects COM 对象持有的内存没有立即释放?或者,为什么 GC 允许进程崩溃,而不是在崩溃之前完成释放的 COM 对象并回收内存?
该应用程序在 Windows 2008 64 位上运行,而我使用 Windows 7 32 位进行开发。我可以让进程在生产盒上崩溃,但不能在我的开发盒上崩溃。我认为这可能是因为我通常在本地使用 Debug 版本在 Visual Studio 中运行,但我也使用 Release 版本在没有调试器的情况下尝试过(不使用调试启动),但即便如此,它也没有使用任何地方。内存在生产中,不会崩溃。
第二个问题:为什么?
编辑:在我之前的实验中,我发现它GC.Collect
本身是不够的,即使我明确地调用它。我有一个实用方法,在每次算法迭代后调用并调用它可以降低内存使用率GC.Collect
。GC.WaitForPendingFinalizers