【发布时间】:2011-01-21 10:46:50
【问题描述】:
我正在使用来自 .NET 的 COM 对象,该对象使用互操作。该对象基本上从套接字获取数据并触发一些事件以供 .NET 层处理。然而,一段时间后,COM 对象停止触发事件,后来发现这是因为它被 GC 收集了。
源代码的结构类似于下面这个:
static void Main(string[] args)
{
MyEventGen gen = new MyEventGen();
WeakReference wr = new WeakReference(gen);
gen.ReceiveDataArray +=
new _IMyEventGenEvents_ReceiveDataArrayEventHandler(gen_ReceiveDataArray);
while (true)
{
Thread.Sleep(1000);
Console.WriteLine(wr.IsAlive);
}
}
static void gen_ReceiveDataArray(ref Array indices, ref Array values)
{
// do nothing
}
到目前为止我所知道的:
据我了解,对象
gen不应以任何方式进行垃圾回收。 因为该对象在Main范围内仍处于活动状态。但是目前的结果显示对象被GC回收了。该对象仅在构建为发布并在不调试的情况下运行时进行垃圾收集。在调试器下运行 Debug 构建/运行两种模式都可以。
程序将在第一个 Gen #0 集合之后精确打印第一个“False”。
通过访问
while循环中的对象,例如Console.WriteLine(gen.ToString()),防止它被GC'd!通过添加
Program类的另一个静态字段来保留其引用也可以防止它被 GC。尝试不同的数据负载,我发现 GC 仅在 Private Bytes 超过 ~ 3X MB 的阈值时收集对象。
检查CLRProfiler,提到的对象被怀疑被GC'd。
我是否遗漏了一些重要的 .NET GC 概念?是否可以获得对象被 GC 的原因?这可能是已知的 GC 错误吗?
我正在使用 VS 2008 + .NET 3.5 SP1。欣赏你的想法。谢谢!
【问题讨论】:
标签: c# .net com garbage-collection com-interop