为什么对象仍然活着?
只是做了一些练习,并突破这个例子。我发现早期创建的列表成员的引用仍然存在,为什么?为什么对象仍然活着?
anotherShoe
和newShoe
仍然具有分配给其参考成员的值,但正如您所看到的那样,实际的对象已被清除。我知道我可以为它们分配空值,但是当它们的参考对象已经被List<T>.Clear()
时,它们不会被自动清空/垃圾收集?
谢谢。
List<Shoe> shoeCloset = new List<Shoe>();
shoeCloset.Add(new Shoe() { styles = Styles.Sneakers, colour = "Red" });
shoeCloset.Add(new Shoe() { styles = Styles.Sandals, colour = "Green" });
shoeCloset.Add(new Shoe() { styles = Styles.Flipflops, colour = "Yellow"});
shoeCloset.Add(new Shoe() { styles = Styles.Loafers, colour = "Brown" });
shoeCloset.Add(new Shoe() { styles = Styles.Wingtips, colour = "Blue" });
//int numberOfShoes = shoeCloset.Count;
//foreach (Shoe shoe in shoeCloset)
//{
// shoe.styles = Styles.Sneakers;
// shoe.colour = "White";
//}
shoeCloset.RemoveAt(3);
Shoe newShoe = shoeCloset[2];
Shoe anotherShoe = shoeCloset[1];
anotherShoe.colour = "Grey";
anotherShoe.colour = "Green";
if (shoeCloset.Contains(anotherShoe))
{
Console.WriteLine("Contains another shoe");
}
shoeCloset.Clear();
anotherShoe.ToString(); //<---this still contains values after shoeCloset has been cleared.
newShoe.ToString(); //<---this still contains values after shoeCloset has been cleared.
对象实例的时候,对于任何执行代码没有可能的方式来以后再访问这些垃圾收集。由于您通过两个局部变量继续引用这两个对象,因此这些对象是可访问的,因此不符合垃圾回收的条件。
垃圾回收的重点在于您无需担心。你永远不会(除了一些边缘案例,如unsafe
代码和弱引用)尝试访问一个对象,并发现你试图访问的对象已被垃圾收集。
快速提示:从'using'语句中返回'IEnumerable'(并且查询使用'using'变量)很容易导致访问一个处置对象。这是一个边缘案例,但需要注意。 +1为正确的答案,但。 – BradleyDotNET 2014-10-08 20:52:02
@BradleyDotNET托管资源的处理与垃圾回收器收集管理对象完全分开。当你自己管理一个对象时,你可能会弄错它;对于GC所管理的那些对象,它不会错误。 – Servy 2014-10-08 20:53:22
'Clear()'不处理对象,它只切割列表和实例化对象之间的引用。这个是正常的。您仍然有一些参考指向前两个对象,因此它们不会被GC处置。 – Vlad 2014-10-08 20:24:13
你的前提是错误的。 List.Clear()只是清除列表 - 从列表中删除对象。但只要引用对象存在垃圾收集器不能释放它占用的内存。 – 2014-10-08 20:24:16
你在哪里清除“anotherShoe”的内容,这两行的目的是什么'notherShoe.colour =“Gray”; anotherShoe.colour =“绿色”;'你有没有使用调试器...?你是否熟悉“Null”这个词在转让方面的问题 – MethodMan 2014-10-08 20:24:42