Что происходит во время сбора мусора, если поколение 2 заполнено?

Я перечитываю CLR через С# прямо сейчас и задаю некоторые вопросы о сборке мусора в .NET. В книге после заполнения Пополнения 0 начинается сбор мусора и перемещается все выдающиеся ссылки на объекты для поколения 1.

То же самое происходит, когда поколение 1 заполнено. Но что происходит, когда второе поколение заполнено? Других поколений нет, чтобы переместить ссылки. Является ли размер поколения 2 расширенным с помощью CLR?

Ответы

Ответ 1

Да, он будет расширять размер Generation 2, если это возможно. Если свободного места нет, вы получите OutOfMemoryException.

Ответ 2

Различные поколения мусора собираются не в том, чтобы иметь определенный размер, а о том, как старый мусор. Ни одно из поколений не имеет ограничений по размеру, о которых я знаю.

Ответ 3

По моему мнению, есть только одна куча (по иронии судьбы, она обычно изображается как стек). Объекты продвигаются к поколению 1 не тогда, когда поколение 0 заполняется, но когда они выживают в коллекции. Вкратце, ссылки не "перемещаются", местоположение, используемое для определения места завершения поколений.

Когда куча приближается к заполнению, происходит несколько вещей:

  • Каждое поколение собирается, начиная с 0 и заканчивая 2.
    • Если сбор генерации 0 достаточен, он не будет собирать генерацию 1 и 2.
    • Если сбор генерации 0 не является достаточным, но сбор поколения 1 есть, он не будет собирать генерацию 2.
  • Куча уплотняется (удаляются пробелы)
  • Содействовать поколениям
    • Выжившие поколения 1 помечены как генерация 2.
    • Пожизненное поколение 0 помечено как поколение 1.

Объекты, которые выживают в коллекции, затем переносятся в поколение 0 (если это их первый цикл сбора) или поколение 2 (если они пережили более одной коллекции). Это делается для эффективности, чтобы мы не пытались постоянно собирать долгоживущие объекты.

У вас не хватает места в генерации определенным образом. См. статью для хорошего объяснения.