2014-10-08 73 views
0

只是做了一些练习,并突破这个例子。我发现早期创建的列表成员的引用仍然存在,为什么?为什么对象仍然活着?

anotherShoenewShoe仍然具有分配给其参考成员的值,但正如您所看到的那样,实际的对象已被清除。我知道我可以为它们分配空值,但是当它们的参考对象已经被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. 
+1

'Clear()'不处理对象,它只切割列表和实例化对象之间的引用。这个是正常的。您仍然有一些参考指向前两个对象,因此它们不会被GC处置。 – Vlad 2014-10-08 20:24:13

+1

你的前提是错误的。 List.Clear()只是清除列表 - 从列表中删除对象。但只要引用对象存在垃圾收集器不能释放它占用的内存。 – 2014-10-08 20:24:16

+0

你在哪里清除“anotherShoe”的内容,这两行的目的是什么'notherShoe.colour =“Gray”; anotherShoe.colour =“绿色”;'你有没有使用调试器...?你是否熟悉“Null”这个词在转让方面的问题 – MethodMan 2014-10-08 20:24:42

回答

5

对象实例的时候,对于任何执行代码没有可能的方式来以后再访问这些垃圾收集。由于您通过两个局部变量继续引用这两个对象,因此这些对象是可访问的,因此不符合垃圾回收的条件。

垃圾回收的重点在于您无需担心。你永远不会(除了一些边缘案例,如unsafe代码和弱引用)尝试访问一个对象,并发现你试图访问的对象已被垃圾收集。

+1

快速提示:从'using'语句中返回'IEnumerable'(并且查询使用'using'变量)很容易导致访问一个处置对象。这是一个边缘案例,但需要注意。 +1为正确的答案,但。 – BradleyDotNET 2014-10-08 20:52:02

+1

@BradleyDotNET托管资源的处理与垃圾回收器收集管理对象完全分开。当你自己管理一个对象时,你可能会弄错它;对于GC所管理的那些对象,它不会错误。 – Servy 2014-10-08 20:53:22