经过几分钟的工作,托管内存包含许多未引用的对象,这些对象是通过从互操作程序集中实现接口(interface)创建的。 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)
有什么想法吗?
更新:添加监听器的使用方式。
最佳答案
这是您在 C# 中使用的 COM 对象吗?检查您是否调用过FinalReleaseComObject或 ReleaseCOMObject如果需要的话,释放 RCW。
关于c# - GC 不收集实现互操作程序集接口(interface)的对象,没有根,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7967969/