Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# GC不从互操作程序集中收集实现接口的对象,没有根_C#_Com_Interop_Garbage Collection - Fatal编程技术网

C# GC不从互操作程序集中收集实现接口的对象,没有根

C# GC不从互操作程序集中收集实现接口的对象,没有根,c#,com,interop,garbage-collection,C#,Com,Interop,Garbage Collection,经过几分钟的工作后,托管内存包含许多未引用的对象,这些对象的类型是通过从互操作程序集实现接口创建的。Collect不会从内存中删除对象 看起来.NET为.NET对象创建了COM可调用包装器,而包装器以某种方式保存了对该对象的引用。但如何调查呢 调查: 0:016> !dumpheap -stat Loading the heap objects into our cache. total 905,554 objects Statistics: MT Count Tot

经过几分钟的工作后,托管内存包含许多未引用的对象,这些对象的类型是通过从互操作程序集实现接口创建的。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 0:016> !转储堆-统计 将堆对象加载到缓存中。 共905554件物品 统计数字: MT Count TotalSize更改类名 ... 0x05127ac0 796 9552 796 Application.GenericListener ... 总共905554个对象,总大小:77354192 类型定义如下:

// 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(); //C#代码: 公共类GenericListener:OurEventListener,IDisposable{…} //GenericListener没有终结器 公共抽象类OurEventListener:EventListener{…} //互操作程序集: [Guid(“…”)] [TypeLibType(256)] [接口类型(1)] 公共接口IListener{…} 使用的类型如下所示:

// 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(); var listener=新的GenericListener(); 订阅(侦听器); ... 取消订阅(侦听器); 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> !转储堆-mt 0x05127ac0 将堆对象加载到缓存中。 地址MT大小 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) 0:016> !gcroot 027a11d4 注意:在堆栈上找到的根可能是误报。运行“!help gcroot”以获取 更多信息。 扫描线程0到线程1444 扫描线程2 OSThread b40 扫描线程7 OSThread 1630 扫描线程8 OSThread a8 扫描线程13 OSThread 1328 域(005F2E30):句柄(RefCnt):182d48:根:027a11d4(Application.GenericListener) 有什么想法吗


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

这是您从C#使用的COM对象吗?检查您是否已呼叫或在需要时呼叫以释放RCW。

您自己不处理该对象有什么原因吗?您对垃圾收集器几乎没有控制权,任何控制权都会以性能为代价。您发布的代码非常少,我将访问guest,gc无法收集它的资源,因为它已处理代码。您是否使用CLR托管?我的意思是,您是否在非托管进程中加载托管代码?所有这些对象都调用@Ramhound Dispose。无论如何,GenericListener中没有定义终结器,所以GC应该在对象未被引用时删除它。但事实并非如此。@Aliostad GenericListener被传递给COM对象,但它处于同一过程中。GenericListener被传递给COM对象以订阅其事件。所有留在内存中的侦听器都被取消订阅。