Статьи

GC с низкой задержкой в ​​.NET 3.5

Варианты GC — это статическая оптимизация производительности сборщика мусора .NET. При различных обстоятельствах приложения могут подключиться (до выполнения) к режиму выполнения, который влияет на поведение GC, чтобы лучше соответствовать конкретному рассматриваемому приложению. Для краткого, но полного описания вкусов GC, блог Maoni является отличным источником информации .

В .NET 3.5 (или .NET 2.0 SP1) добавлен дополнительный API, который в некоторых случаях может изменить внешний вид GC. Он доступен как класс System.Runtime.GCSettings , который имеет два свойства: IsServerGC и LatencyMode .

Свойство IsServerGC является свойством только для чтения, которое указывает, выполняется ли приложение на сервере GC. Его нельзя использовать для выбора сервера GC во время выполнения — он отражает только состояние конфигурации приложения или определение разновидности GC хоста CLR.

С другой стороны, свойство LatencyMode принимает значения перечисления GCLatencyMode : Batch , Interactive и LowLatencyПакет соответствует GC-серверу (это значение по умолчанию и единственно возможное значение, когда GC-сервер включен) или рабочей станции GC, не работающей одновременно; Интерактив соответствует параллельной рабочей станции GC. Обратите внимание, что если приложение выполняется на рабочей станции GC, свойство LatencyMode можно использовать для переключения между одновременным и не одновременным сборщиком мусора во время выполнения.

Последнее, наиболее интересное значение перечисления GCLatencyModeLowLatency , которое доступно только при использовании рабочей станции GC. Это значение сигнализирует сборщику мусора, что ваш код в настоящий момент находится в середине кратковременной чувствительной ко времени операции, когда сборка мусора может быть вредной. Это не является ценностью выбора, если вы собираетесь выполнить ракетный код по причинам, которые будут рассмотрены в ближайшее время. Однако это полезно, если вы выполняете анимацию пользовательского интерфейса, и сборка мусора будет мешать работе пользователя.

Режим сбора мусора с низкой задержкой, подразумеваемый значением перечисления LowLatency, предписывает сборщику мусора воздерживаться от выполнения полных сборок, если в этом нет крайней необходимости — например, если в операционной системе недостаточно физической памяти (эффекты подкачки могут быть даже хуже, чем эффекты выполнения полной коллекции). Низкая задержка не означает, что сборщик мусора выключен — частичные сборки (низкого поколения) будут выполняться, но доля сборщика мусора в времени обработки приложения будет значительно ниже.

Использование режима GC с малой задержкой может быть сложным, потому что забыв сбросить его обратно к предыдущему значению может привести к катастрофическим последствиям. Кроме того, количество времени, которое вы хотите провести в режиме GC с малой задержкой, должно быть сведено к минимуму — долгосрочные эффекты после выхода из режима низкой задержки и когда GC активно начинает восстанавливать неиспользуемую память, могут снизить производительность приложения. Наконец, если у вас нет полного контроля над всеми выделениями, происходящими в вашем процессе (например, если вы размещаете плагины или у вас несколько фоновых потоков, выполняющих независимую работу), помните, что переключение в режим GC с низкой задержкой влияет на весь процесс. процесс, и может вызвать нежелательные эффекты для других путей распределения.

Единственный безопасный способ использования режима GC с низкой задержкой находится в ограниченной области выполнения (CER), потому что это единственный способ гарантировать, что режим задержки вернется к своему предыдущему значению. Следующий код (взят из блога Криса Лиона ) демонстрирует, как это можно сделать:

GCLatencyMode oldMode = GCSettings.LatencyMode;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
GCSettings.LatencyMode = GCLatencyMode.LowLatency;
// perform time-sensitive actions here
}
finally
{
GCSettings.LatencyMode = oldMode;
}

При использовании режима GC с малой задержкой рекомендуется принудительно собирать мусор в безопасных точках, когда известно, что чувствительная ко времени работа приостановилась и может позволить приостановить выполнение сбора. Нахождение в режиме низкой задержки без выполнения сбора в течение длительного периода времени может привести к нехватке памяти. Вообще говоря, если приложение чувствительно к срокам сборки мусора, разумно заставить сборщик во время простоя влиять на смещенное перераспределение накладных расходов на сборку мусора в области простоя времени выполнения.