Prevent.NET сбор мусора за короткий промежуток времени


У меня есть высокопроизводительное приложение, которое обрабатывает очень большой объем данных. Он получает, анализирует и отбрасывает огромное количество информации в течение очень коротких периодов времени. Это вызывает изрядное количество оттока объектов, которые я в настоящее время пытаюсь оптимизировать, но это также вызывает вторичную проблему. Когда сбор мусора запускается, он может вызвать некоторые длительные задержки, поскольку он очищает вещи (под длинными я имею в виду от 10 до 100 миллисекунд). В 99% случаев это приемлемо, но для коротких окон времени около 1-2 минут мне нужно быть абсолютно уверенным, что сбор мусора не вызывает задержки. Я знаю, когда эти периоды времени будут происходить заранее, и мне просто нужен способ убедиться, что сбор мусора не произойдет в течение этого периода. Приложение написано на C# с использованием .NET 4.0 Framework и использует как управляемый, так и неуправляемый код, если это имеет значение.

мои вопросы;

  1. можно ли ненадолго приостановить мусор Сбор за всю программу?
  2. можно ли использовать систему.СБОРЩИК МУСОРА.Collect () для принудительной сборки мусора перед окном мне нужно освободить от сборки мусора, и если я это сделаю, как долго я буду собирать мусор бесплатно?
  3. какие советы есть у людей по минимизации необходимости сбора мусора в целом?

Примечание-эта система довольно сложна с большим количеством различных компонентов. Я надеюсь избежать перехода к подходу, где я должен реализовать пользовательский интерфейс IDisposable для каждого класса программы.

2 53

2 ответа:

.NET 4.6 добавлены два новых метода:GC.TryStartNoGCRegion и GC.EndNoGCRegion только для этого.

GCLatencyMode oldMode = GCSettings.LatencyMode;

// Make sure we can always go to the catch block, 
// so we can set the latency mode back to `oldMode`
RuntimeHelpers.PrepareConstrainedRegions();

try
{
    GCSettings.LatencyMode = GCLatencyMode.LowLatency;

    // Generation 2 garbage collection is now
    // deferred, except in extremely low-memory situations
}
finally
{
    // ALWAYS set the latency mode back
    GCSettings.LatencyMode = oldMode;
}

это позволит Вам отключить GC столько, сколько вы можете. Он не будет делать никаких больших коллекций объектов, пока:

  • вы называете GC.Collect()
  • установить GCSettings.LatencyMode к чему-то другому, чем LowLatency
  • ОС посылает сигнал низкой памяти в CLR

пожалуйста, будьте осторожны при этом, потому что использование памяти может подняться очень быстро, пока вы находитесь в этом try блок. Если GC собирает, он делает это для причина, и вы должны только серьезно рассмотреть это, если у вас есть большой объем памяти в вашей системе.

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

вот некоторые статьи MSDN это тоже может помочь:

Примечание:GCSettings.LatencyMode = GCLatencyMode.LowLatency можно установить только если GCSettings.IsServerGC == false. IsServerGC можно изменить в App.config:

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