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