GC不收集从interop程序集实现接口的对象,没有root

时间:2011-11-01 14:27:52

标签: c# com interop garbage-collection

在几分钟的工作之后,托管内存包含许多通过实现interop程序集的接口创建的类型的未引用对象。 GC.Collect不会从内存中删除对象。

看起来.NET为.NET对象创建了COM可调用包装器,而包装器以某种方式保存了对象的引用。但是如何调查呢?

调查:

0:016> !dumpheap -stat
Loading the heap objects into our cache.
total 905,554 objects
Statistics:
        MT    Count    TotalSize       Change Class Name
...
0x05127ac0      796        9,552          796 Application.GenericListener
...
Total 905,554 objects, Total size: 77,354,192

类型定义如下:

// C# code:
public class GenericListener: OurEventListener, IDisposable { ... }
// GenericListener does NOT have finalizer
public abstract class OurEventListener : EventListener { ... }

//Interop assembly:
[Guid("...")]
[TypeLibType(256)]
[InterfaceType(1)]
public interface IListener { ... }

类型使用如下:

var listener = new GenericListener();
ourComObject.Subscribe(listener);
...
ourComObject.Unsubscribe(listener);
listener.Dispose();

物件:

0:016> !dumpheap -mt 0x05127ac0
Loading the heap objects into our cache.
 Address       MT     Size
027a11d4 05127ac0       12    2 Application.GenericListener
0326d354 05127ac0       12    2 Application.GenericListener
09c5812c 05127ac0       12    2 Application.GenericListener
09c83000 05127ac0       12    2 Application.GenericListener
...

对象是根源:

0:016> !gcroot 027a11d4
Note: Roots found on stacks may be false positives. Run "!help gcroot" for
more info.
Scan Thread 0 OSThread 1444
Scan Thread 2 OSThread b40
Scan Thread 7 OSThread 1630
Scan Thread 8 OSThread a8
Scan Thread 13 OSThread 1328
DOMAIN(005F2E30):HANDLE(RefCnt):182d48:Root:  027a11d4(Application.GenericListener)

有什么想法吗?

更新:添加监听器的使用方式。

1 个答案:

答案 0 :(得分:0)

这是您在C#中使用的COM对象吗?检查您是否已根据需要调用FinalReleaseComObjectReleaseCOMObject,以释放RCW。