2014-10-08 2 views
0

Просто выполните некоторую практику и остановитесь на этом примере. Я обнаружил, что ссылки ранее созданных членов списка были еще живы, почему?Почему объект все еще жив?

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. 
+1

'Clear()' не удаляет объекты, он только сокращает ссылку между вашим списком и созданным экземпляром объекта. Это нормально. У вас все еще есть ссылки, указывающие на первые 2 объекта, поэтому они не будут удалены GC. – Vlad

+1

Ваша предпосылка неверна. List.Clear() просто очищает список - удаляет объект из списка. Но до тех пор, пока ссылается на объект, Мусорщик не может освободить память, которую он занимает. –

+0

, где вы очищаете содержимое 'anotherShoe' и какова цель этих двух строк' notherShoe.colour = "Gray"; anotherShoe.colour = "Green"; 'вы даже использовали отладчик ...? вы знакомы со словом «Null» в отношении назначения – MethodMan

ответ

5

Объектные экземпляры собираются в мусор, когда нет возможности, чтобы любой исполняемый код когда-либо обращался к ним снова. Поскольку вы держите ссылки на эти два объекта через две локальные переменные, которые все еще находятся в области видимости, эти объекты доступны и, следовательно, не имеют права на сбор мусора.

Весь смысл сбора мусора для вас не нужно беспокоиться об этом. Вы никогда не станете (за исключением нескольких краевых случаев, таких как код unsafe и слабых ссылок), попробуйте получить доступ к объекту и узнать, что объект, к которому вы пытаетесь получить доступ, был собран мусором.

+1

Быстрое предостережение: возврат 'IEnumerable' из инструкции' using' (и запрос использует переменную 'use') может легко привести к доступу к удаленному объекту. Это краевой случай, но тот, о котором нужно знать. +1 для правильного ответа. – BradleyDotNET

+1

@BradleyDotNET Утилизация управляемых ресурсов полностью отделена от сбора управляемых объектов сборщиком мусора. Когда вы сами управляете объектом, вы можете ошибаться; для тех объектов, которые управляет GC, это не будет ошибкой. – Servy

Смежные вопросы