Определение, какой сборщик мусора работает

Я запускаю большое приложение.net 4.0 x86 на Windows Server 2003 x64 (2x Xeon 4 core Procs) и сталкиваюсь с проблемами, когда мое приложение ~2-3 раза в день зависает на 30 секунд, а затем возобновляет работу в обычном режиме. Приложение перезагружается только раз в неделю и потребляет 400-800 мегабайт памяти, поэтому я предполагаю, что эти зависания являются сборкой мусора. Я вижу только зависания в журналах, но не в реальном времени, или я бы проверил диспетчер задач, чтобы подтвердить.

Я пытаюсь выяснить, какой.Net 4 GC работает, и как либо переключить GC на новый параллельный фоновый gc, если это не так, либо как подтвердить, что это на самом деле GC (Procmon не показывает.Net инструменты на сервере Win2k3).

2 ответа

Решение

Вы работаете на серверной версии Windows, по умолчанию вы получите серверную версию сборщика мусора. Что не делает фоновые коллекции, мусор собирается несколькими потоками, поэтому случайные наблюдаемые паузы не являются чем-то необычным. Вы можете принудительно установить версию рабочей станции с помощью файла app.exe.config:

<configuration>
   <runtime>
      <gcServer enabled="false"/>
   </runtime>
</configuration>

Также просмотрите документы для метода GC.RegisterForFullGCNotification(), чтобы узнать, как справиться с побочным эффектом пауз.

.NET версии 4.5 будет поддерживать фоновые коллекции для сервера GC.

Я повторно опубликовал этот ответ в своем блоге: http://dave-black.blogspot.com/2012/04/how-to-determine-which-garbage.html

Вы можете определить, какую версию GC вы используете, используя 2 метода:

  1. вызов свойства System.Runtime.GCSettings.IsServerGC
  2. присоединение к процессу с использованием WinDbg и проверка количества потоков GC у вас с помощью команды "!sos.threads" без кавычек и (согласно приведенным ниже критериям)...

Вы не сказали, какое у вас приложение. Если вы используете консольное приложение, приложение WinForm или службу Windows, вы получите GC для рабочей станции. То, что вы работаете на серверной ОС, не означает, что вы получите серверную версию GC. Если ваше приложение не размещено на компьютере с несколькими процессорами, по умолчанию вы получите GC Workstation - Concurrent. Если ваше приложение размещено на машине с несколькими процессами, вы получите ServerGC по умолчанию.

Любое приложение IIS или CLR по умолчанию будет работать в режиме ServerGC.

Следующее относится к любому данному управляемому процессу.NET:

Рабочая станция GC

  • универсальная машина
  • Всегда приостанавливает потоки
  • 1 эфемерная куча GC (SOH), 1 куча LOH GC
  • Работает на потоке, который вызвал GC
  • Приоритет потока совпадает с потоком, который вызвал GC

Рабочая станция GC - Concurrent

  • Работает только одновременно в Gen2/LOH (полная коллекция)
  • Взаимоисключающие с режимом сервера
  • Чуть больше рабочий набор
  • Поток GC истекает, если через некоторое время не используется
  • 1 эфемерная куча GC (SOH), 1 куча LOH GC
  • Выделенная нить GC
  • Приоритет потока - Нормальный

Сервер GC

  • Большие размеры сегментов
  • Быстрее, чем рабочая станция GC
  • Всегда приостанавливает потоки
  • 1 эфемерная куча GC (SOH) для каждого логического процессора (включая гиперпотоковую), 1 куча LOH GC для каждого логического процессора (включая гиперпотоковую)
  • Выделенные темы GC
  • Приоритет темы - THREAD_PRIORITY_HIGHEST

В каждом управляемом процессе есть только 1 поток финализатора независимо от режима GC. Даже во время одновременной работы GC управляемые потоки дважды приостанавливаются (блокируются) для выполнения некоторых этапов GC.

Редко известный факт заключается в том, что даже если вы попытаетесь установить режим сервера GC, вы можете не работать в режиме Server GC; GC в конечном итоге определяет, какой режим будет оптимальным для вашего приложения, и БУДЕТ переопределять ваши настройки, если он определит, что ваши настройки ServerGC негативно отразятся на вашем приложении. Кроме того, любое размещенное приложение CLR, запущенное на однопроцессорной машине, будет иметь какие-либо ручные настройки GC - в этом случае CLR всегда будет использовать режим GC Workstation.

В CLR 4.0 все меняется немного

  • Concurrent GC теперь является Background GC
  • Фоновый GC применяется только к рабочей станции GC
  • Старый (Concurrent GC):
    • Во время полного GC Разрешенные выделения до конца размера эфемерного сегмента
    • В противном случае приостанавливает все остальные потоки.
  • Новый (Background GC):
    • Допускает эфемерные GC одновременно с Background GC, если необходимо
    • Производительность намного быстрее
  • Сервер GC всегда блокирует потоки для сбора любого поколения

В CLR 4.5 все немного меняется... опять

  • Фоновый сервер GC:
    • Сервер GC больше не блокирует. Вместо этого он использует выделенные фоновые потоки GC, которые могут работать одновременно с пользовательским кодом - см. MSDN: Фоновый сервер GC

Таким образом, в.NET 4.5+ все приложения теперь имеют фоновый GC, доступный для них, независимо от того, какой GC они используют.

Улучшения в.NET 4.7.1 GC

.NET Framework 4.7.1 вносит изменения в сборщик мусора (GC) для улучшения производительности выделения, особенно для распределений большой кучи объектов (LOH). Это связано с архитектурным изменением разделения блокировки кучи на 2 для кучи малых объектов (SOH) и LOH. Приложения, которые выполняют много выделений LOH, должны видеть снижение конкуренции за блокировку выделения и видеть лучшую производительность. Эти улучшения позволяют выделять LOH, пока Background GC (BGC) охватывает SOH. Обычно распределитель LOH ожидает всей продолжительности процесса очистки BGC, прежде чем он сможет удовлетворить запросы на выделение памяти. Это может снизить производительность. Вы можете наблюдать эту проблему в GCStats PerfView, где есть таблица "Пауза выделения LOH (из-за фонового GC) > События 200 мсек". Причиной паузы является "Ожидание BGC для потоковой обработки свободных списков". Эта функция должна помочь смягчить эту проблему.

Другие вопросы по тегам