Сборка мусора объекта, созданного в бесконечном цикле - PullRequest
6 голосов
/ 08 июля 2010

У меня очень простой вопрос.

Я пишу такой цикл:

while(true)
{
   MyTestClass myObject = new MyTestClass();
}
  1. Когда будет объект, созданный в петля, сборка мусора?
  2. Кроме того, для каждой итерации что новая ячейка памяти выделено для ссылки myObject?
  3. Что если я напишу myObject = null; в конце каждой итерации?

Ответы [ 5 ]

10 голосов
/ 08 июля 2010
  1. всякий раз, когда GC хочет, честно говоря;переменная никогда не читается, поэтому она всегда имеет право
  2. myObject - это переменная , которая имеет фиксированную позицию в стеке для ссылки;однако каждый new MyTestClass() является отдельным объектом , созданным где-то в доступном пространстве кучи;каждый раз разные
  3. без разницы;Строго говоря, есть некоторые сложности, связанные с фактической точкой объявления переменной (в IL) и с тем, как на самом деле реализуется while, но это будет видно только после выхода из цикла.И поскольку на каждой итерации вы сразу выделяете ее, здесь нет ощутимой разницы
5 голосов
/ 08 июля 2010

Когда будет создан объект, созданный в цикле, сборщик мусора?

В какой-то момент после удаления последней ссылки на него.Новая ссылка создается и удаляется на каждой итерации цикла, поэтому GC может собирать эти объекты по своему усмотрению.На практике это может произойти, когда ваша программа полностью заполняет нулевое поколение.

Кроме того, для каждой итерации новое место в памяти выделяется для ссылки myObject?*

Да.

Что если я напишу myObject = null; в конце каждой итерации?

Это не будет иметь никакого значения.Установка myObject = null; удаляет эту ссылку на объект, но ссылка удаляется в любом случае, когда переменная myObject переназначается в следующей итерации цикла.

4 голосов
/ 08 июля 2010

Давайте добавим некоторый код, который фактически использует объект, чтобы прояснить, что на самом деле происходит:

while(true) {
  // Here a new instance is created in each iteration:
  MyTestClass myObject = new MyTestClass();
  // Here the instance is still in use
  // until here:
  myObject.CallSomething();
  // Here the instance isn't used any more,
  // so the GC can collect it if it wants to.
  // Setting the reference to null here:
  myObject = null;
  // is useless, as the GC already knows that the
  // instance is unused before that time.
}
3 голосов
/ 08 июля 2010

Давайте проясним несколько вещей. Каждый раз, когда вы нажимаете внутри цикла, myObject будет назначаться новому адресу. Таким образом, весь этот цикл всегда выделяет новые адреса памяти для одного имени переменной. Таким образом:

  1. GC будет собирать все предыдущие выделения, вероятно, почти сразу, поскольку переменная никогда не используется.
  2. Да.
  3. Не имеет значения. Переменная все еще не используется.
0 голосов
/ 08 июля 2010

Как дополнение ко всем остальным ответы:

Вы можете сделать свой класс структурой. Тогда он будет в стеке и будет выбрасываться для каждой итерации. Если ваша структура создает новые классы, тогда вы вернетесь на круги своя. И если ваша структура велика, это может отрицательно повлиять на производительность, но в противном случае, если она небольшая, это может положительно повлиять на производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...