Prevent.NET сбор мусора за короткий промежуток времени
У меня есть высокопроизводительное приложение, которое обрабатывает очень большой объем данных. Он получает, анализирует и отбрасывает огромное количество информации в течение очень коротких периодов времени. Это вызывает изрядное количество оттока объектов, которые я в настоящее время пытаюсь оптимизировать, но это также вызывает вторичную проблему. Когда сбор мусора запускается, он может вызвать некоторые длительные задержки, поскольку он очищает вещи (под длинными я имею в виду от 10 до 100 миллисекунд). В 99% случаев это приемлемо, но для коротких окон времени около 1-2 минут мне нужно быть абсолютно уверенным, что сбор мусора не вызывает задержки. Я знаю, когда эти периоды времени будут происходить заранее, и мне просто нужен способ убедиться, что сбор мусора не произойдет в течение этого периода. Приложение написано на C# с использованием .NET 4.0 Framework и использует как управляемый, так и неуправляемый код, если это имеет значение.
мои вопросы;
- можно ли ненадолго приостановить мусор Сбор за всю программу?
- можно ли использовать систему.СБОРЩИК МУСОРА.Collect () для принудительной сборки мусора перед окном мне нужно освободить от сборки мусора, и если я это сделаю, как долго я буду собирать мусор бесплатно?
- какие советы есть у людей по минимизации необходимости сбора мусора в целом?
Примечание-эта система довольно сложна с большим количеством различных компонентов. Я надеюсь избежать перехода к подходу, где я должен реализовать пользовательский интерфейс IDisposable для каждого класса программы.
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 это тоже может помочь:
- Режимы Задержки
- Ограниченные Области Выполнения (вот почему мы называем
PrepareConstrainedRegions()
)Примечание:
GCSettings.LatencyMode = GCLatencyMode.LowLatency
можно установить только еслиGCSettings.IsServerGC == false
.IsServerGC
можно изменить вApp.config
:<runtime> <gcServer enabled="false" /> </runtime>