Когда GC решает собрать поколение 2? - PullRequest
8 голосов
/ 21 декабря 2011

В течение дня я вижу много коллекций второго поколения в нашем сервисе windows.

Когда GC решает сделать полный сбор вместо того, чтобы собирать только Gen1 и Gen0 или только Gen0?

Ответы [ 2 ]

9 голосов
/ 21 декабря 2011

Читать http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx и связанные статьи для получения дополнительной информации.В общем, gen2 собирается «при необходимости».

Одна вещь, которая может вызвать чрезмерные коллекции Gen2, - это куча больших объектов (LOH).Когда LOH заполняется, он запускает полную коллекцию.Если ваше приложение выделяет и освобождает множество крупных объектов (80 КБ или более), это вполне может стать вашей проблемой.

См. CLR Inside Out: куча больших объектов не обнаружена .

Также рассмотрите возможность использования серверного сборщика мусора в вашем сервисе.Это обычно обеспечивает лучшую производительность (меньше коллекций).Добавьте это в свой файл app.config:

<configuration
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration> 
5 голосов
/ 21 декабря 2011

Обычно сбор инициируется (при любом поколении), когда выполняется одно из следующих условий

  • Распределение превышает порог. Я смутно помню, как это было динамично, исходя из текущих потребностей. Кто-нибудь может подтвердить / опровергнуть?
  • Недостаточно памяти
  • Вызывается через GC.Collect ()

Может быть, я пропускаю другой сценарий, но обычно это так. Первый - это то, что обычно запускает коллекцию, и, учитывая, что собирать G2 (относительно) дороже, чем G0, вы видите их меньше.


Для ответа на вопрос в комментарии:
Каждое поколение имеет порог, который при попадании вызовет сбор. Gen0 может быть 5 МБ, и будет запущен, когда он будет заполнен. После запуска GC, если у вас все еще есть 5 МБ, я думаю, это увеличит лимит. Если этого не произошло, то каждое распределение вызовет сбор, и у вас возникнет проблема. Gen2 может быть 20 Мб (заметьте, я здесь составляю цифры), и там применяется та же логика.

Для примера из учебника давайте рассмотрим простой сценарий.

  1. Новым приложениям, выделенным объектам, и все помещаются в Gen0 на общую сумму 3 МБ данных. (это не всегда так, но сделайте вид, что это так)
  2. GC попадает, и 1 МБ из этого перемещается в G1, остальное очищается.
  3. G0 теперь свободен, а G1 имеет 1 МБ.
  4. Создается больше объектов, и происходит больше GC. Через некоторое время G1 наполняется, а некоторые перемещаются в G2.
  5. Объекты остаются там до тех пор, пока не заполнится G2, а затем очищаются , если не используются . Если на объект все еще ссылаются, он будет оставаться в G2, пока не будет очищен .

Полный сбор данных стоит дорого, и я видел, как дни проходили без единого случая. Конечно, это было в системе с> 64 ГБ оперативной памяти, и в этом не было необходимости.

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