Сборка "мусора" объекта создается в бесконечном цикле

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

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

while(true)
{
   MyTestClass myObject = new MyTestClass();
}
  1. То, когда будет объект создан в цикле, собрало "мусор"?
  2. Кроме того, для каждого повторения случается так, что новая ячейка памяти выделяется myObject ссылке?
  3. Что, если я пишу myObject = null; в конце каждого повторения?
6
задан James Black 8 July 2010 в 10:02
поделиться

5 ответов

  1. откровенно говоря, всякий раз, когда GC захочет; переменная никогда не читается, поэтому она всегда допустима
  2. myObject - это переменная - которая имеет фиксированную позицию в стеке для ссылки; однако каждый new MyTestClass () представляет собой отдельный объект , созданный где-то в доступном пространстве кучи; каждый раз разный
  3. никакой разницы нет; строго говоря, есть некоторые сложности, связанные с фактической точкой объявления переменной (в IL) и тем, как на самом деле реализовано , а - но это будет отображаться только после выхода из цикла. И поскольку на каждой итерации вы сразу выделяете его, здесь нет ощутимой разницы
10
ответ дан 8 December 2019 в 05:52
поделиться

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

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

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

Да.

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

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

5
ответ дан 8 December 2019 в 05:52
поделиться

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

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.
}
4
ответ дан 8 December 2019 в 05:52
поделиться

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

  1. Сборщик мусора соберет все предыдущие выделения памяти, вероятно, почти сразу, поскольку переменная никогда не используется.
  2. Да.
  3. Неважно. Переменная все еще не используется.
3
ответ дан 8 December 2019 в 05:52
поделиться

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

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

0
ответ дан 8 December 2019 в 05:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: