1
  1. 我有用 Wea​​kReferences 填充的字典。
  2. Web 服务 A:创建对象并将其放置在弱引用字典上。(1)
  3. Web 服务 A 有时会保留具有强引用的对象,有时则不会。

我的问题:

我无法跟踪应该从弱引用字典中删除的对象,因为垃圾收集器不会立即收集它们,它只会在随机且不可预测的时间后收集。

行为不一致,例如

示例 1:按预期工作,变量 ex1 立即被收集。

Sub Example1(id as integer)
Dim ex1 as new Object
dim t as new WeakReference With {.target = ex1};
WeakReferenceDictionary.add(id,ex1)
End Sub<br>

Example2 '这不起作用,ext1 没有立即收集

Sub Example1(id as integer)
  Dim ex1 as new Object
  dim t as new WeakReference With {.target = ex1};
  WeakReferenceDictionary.add(id,ex1)

  otherclass.refObject = ex1
  otherclass.refObject = Nothing

End Sub<br>

我努力了。
将 WeakDictionary 放在 Module1 内(是一个控制台应用程序)。
GC.Collect
GC.Collect(0)
GC.Collect(1)
GC.Collect(2)

我的问题。无论如何,即使它会降低我的应用程序的性能,是否真的强制进行垃圾收集。我知道我不应该将 GC 用于逻辑目的,但对于我的解决方案来说,这样做真的很方便。

4

2 回答 2

2

我将以免责声明开始这篇文章:我非常怀疑你是否选择了正确的方法来依赖垃圾收集内部,因为不能保证,不可预测,即使现在测试可以工作,你的代码可能会与任何 .NET 中断补丁发布。

您的对象可能未被收集的原因有多种:

  1. 您正在调试器下运行或已在调试模式下构建。这将稍微延长对象的生命周期(JIT 不会急切地将变量内容标记为未使用,以便即使变量超出范围,您也可以调试变量)。
  2. 您将 GC.Collect 调用放置在错误的位置
  3. 尽管您的对象有一个,但您没有调用 WaitForPendingFinalizers

也许还有其他原因。

那么如何解决这个问题呢?不要依赖GC。依赖确定性操作,例如实现和调用 Dispose 或切换到引用计数技术。

于 2012-09-07T21:18:19.227 回答
0

感谢exaceratedexpert;阅读文章 www.sellsbrothers.com/writing/refcount_rotor.doc,发现真正强制 GC 以确保所有应该被处理的对象实际上都将以可预测的方式被处理是不切实际的。

必须实现引用计数器(如文章所示)。

我发现的另一个解决方案是创建一个包含已创建的特定类的所有对象的数组,然后使用根节点通过反射执行第二次查看,然后比较两者并找出谁是missig。这种方法将确保获得干净一致的结果,但会消耗太多资源,不得不进行完整的根子扫描。

谢谢你们的回答。

于 2012-09-08T16:48:56.757 回答