【问题标题】:Releasing Com Objects Doesnt Affect Memory Usage释放 Com 对象不影响内存使用
【发布时间】:2018-06-15 00:58:52
【问题描述】:

当我通过 Marshall.ReleaseComObject 方法释放 com 对象时,应用程序的内存使用不会改变。不使用 Marshall.ReleaseComObject,使用垃圾收集器 (GC.Collect()) 可以释放 com 对象的内存区域,但 UI 会变慢。

所以我的问题是,释放 com 对象的最佳方法是什么?

【问题讨论】:

    标签: c# .net garbage-collection arcgis arcobjects


    【解决方案1】:

    试试这个,

    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oApp);
    oApp = null; // Set each COM Object to null
    //
    // After all of the COM objects have been released and set to null, do the following:
    GC.Collect(); // Start .NET CLR Garbage Collection
    GC.WaitForPendingFinalizers(); // Wait for Garbage Collection to finish
    

    【讨论】:

      【解决方案2】:

      如果对象实现了finalizer,调用gc表示将这个对象引用放入finalization queue,表示不会立即释放。

      【讨论】:

        【解决方案3】:

        虽然有点过时(从 ArcGIS 10.0 开始),但发布规则以及如何执行此操作在 http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#/Releasing_COM_references/0001000004tm000000/ 中有很好的描述。

        有两种方法可以做到这一点。通过使用Marshal.ReleaseCOMObject 或ComReleaser-class,它本质上是前者的包装器。但是,您可能对完全相同的 com 对象有多个引用,这就是为什么调用 ReleaseComObject 不会最终释放该对象,而只是将内部引用计数器减一。只有当该计数器等于 0 时,对象才会实际上被释放。例如,请参见此处:

        var f1 = featureClass.GetFeature(1);
        // retrieve the exact same feature again
        var f2 = featureClass.GetFeature(1);
        

        虽然从 .NET 的角度来看,f1 和 f2 是完全不同的对象,但底层的 com 对象是相同的(假设唯一实例化,这超出了本问题的范围)。在f1 或f2 上调用Marshal.ReleaseComObject 时,您只会将此com 对象的内部引用计数器减1,而使一个引用保持活动状态。

        GC.Collect 但是没有任何效果,因为它无法处理 com 对象所在的 unmanaged 资源。垃圾收集器只能释放 托管 资源。因此,调用GC.Collect 只会(如果有的话)释放runtime-callable-wrapper,它是围绕非托管对象的托管包装器。然而,后者仍然存在于内存中,并且可能会产生死泄漏。

        话虽如此,最终释放 com-objects 的唯一方法是在循环中调用 Marshal.ReleaseComObject 直到引用计数器为零。

        while(Marshal.ReleaseComObject(myObject) > 0);
        

        之后您可能会也可能不会致电GC.Collect。但是我不建议这样做,因为垃圾收集器最清楚何时释放托管对象。强制它这样做充其量会按预期工作,最坏的情况是只会使您的代码变慢而没有任何积极影响。 GC 是不确定的过程,您无法真正影响它。

        【讨论】:

          【解决方案4】:

          最好的方法是使用 ComReleaser 或 Marshal.ReleaseComObject 方法。调用 GC.Collect 方法过多会导致应用程序变慢。让 GC 在需要时完成其工作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-11-06
            • 2015-09-25
            • 2012-09-17
            • 1970-01-01
            • 2015-07-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多