跟踪应该为逻辑目的收集的对象

时间:2012-09-07 21:08:59

标签: .net garbage-collection weak-references

  1. 我的字典填充了WeakReferences。
  2. Web服务A:然后在弱引用字典上创建对象和位置。 (1)
  3. Web服务A有时会保留具有强烈引用的对象,有时则不会。
  4. 我的问题:

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

    行为不一致,例如

    示例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>
    

    示例2'这不起作用,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用于逻辑目的,但是我的解决方案非常方便。

2 个答案:

答案 0 :(得分:2)

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

可能无法收集您的对象有多种原因:

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

    也许还有其他原因。

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

答案 1 :(得分:0)

感谢exacerbatedexpert; 阅读文章www.sellsbrothers.com/writing/refcount_rotor.doc,发现真正迫使GC确保所有待处置的物体实际上都会以可预测的方式处理是不切实际的。

必须实施参考计数器(如文章所示)。

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

感谢您的回答。

相关问题