确定C#中是否已销毁对象(即在任何地方都找不到)

时间:2014-06-18 15:48:52

标签: c# object memory-management memory-leaks destroy

我确定之前已经问过这个问题,我只是不知道要搜索的正确术语。在我正在研究的C#程序中,我有一个跟踪对象的List。这些对象也可以通过其他对象的引用显示在屏幕上。

有时候从列表中删除一个对象后,它仍然暂时可供其他对象使用(应该是这样)...完成这些对象后,我想确保对象100%消失而不是<罢工>留在记忆中仍然被一个被遗忘的物体引用......我怎么能这样做?

要明确的是,这并不是作为已发布程序的一部分发生的,仅用于调试。

3 个答案:

答案 0 :(得分:2)

你通常不能。 GC旨在处理幕后的内存管理,并且非常具体地完成它的工作,并且最好不要吝啬。特别是,代码的其他部分可能会保留对要删除的项目的引用,这应该阻止其收集。这就是内存管理语言的本质,例如C#。

然而,有人说,有几种方法可以检查物品的处理时间。最简单的方法是创建一个简单的析构函数并断点它,让你看到&#34;看到&#34;每当收集一个物体时。

~MyClass()
{ // Breakpoint here
}

另一种方法是为对象创建一个WeakReferences的静态列表,每个对象在创建时都会订阅这些列表。但是,请确保保留其他列表,因为弱引用专门用于允许垃圾回收,允许您跟踪对象的销毁情况。另一个列表是保持对象存活的必要条件。另请注意,在.NET 4.5中,有一个generic version of WeakReference。编辑:在看到您的问题更新后,这绝对是我推荐的解决方案。您还可以通过Linq

快速查询哪些对象仍在被引用
var leftoverObjects = WeakCache
    .Select(wr => wr.Target)
    .OfType<MyObject>() // Only if you're not using that Generic Weak Reference
    .Except(ObjectList); // filters away objects in the List

请注意,上面的查询会创建一个具有强引用的结果,因此一旦运行,只要引用了结果,它就会将这些对象保留在内存中。

如果你有某种非托管内存支持你的对象,这正是IDisposable接口的设计目的。

更新:最后,如果你必须这样做,你可以强制GC到Collect。当你开始扭曲有助于优化GC的Generations时,通常会建议不要这样做。

答案 1 :(得分:2)

我猜你需要这个用于测试目的。在这种情况下,我建议使用内存分析器,例如ANTS Memory ProfilerJetBrains dotTrace。您可以找到更完整的个人资料列表here

答案 2 :(得分:0)

没有简单的方法可以“向后”查找对象引用,基本上您需要使用反射来遍历应用程序中存在的所有对象和结构并检查所有引用。您只需要确保使用该引用的所有代码在完成后确实将其删除。

检查是否有任何实时引用(但不是它们所在的位置)的一种方法是保留一个对不再使用的对象的弱引用列表。弱引用不会阻止对象被收集,但您可以使用它们来检查对象是否已被收集。

由于无法保证在任何特定时间内收集对象,您无法确定它是否是保持对象存活的实际引用,但是对象存活的时间越长,您就越有可能在某个地方提到它。