Подтвердить что ты не робот

Блокировка GC.Collect()?

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

Итак, я вызываю GC.Collect() перед началом теста, но не уверен, что сбор продолжает работать в отдельном потоке и т.д. и немедленно возвращается. Если он работает в потоке BG, я хочу знать, как его называть синхронно или, по крайней мере, ждать, пока он не завершит сбор.

4b9b3361

Ответ 1

Как состояния MSDN - используйте этот метод для try, чтобы восстановить всю недоступную память.

В любом случае, если он начнет сборку мусора, вы должны дождаться завершения всех финишеров до начала бенчмаркинга.

   GC.Collect();

   GC.WaitForPendingFinalizers();

Ответ 2

Поскольку .NET Framework 4.5 вы можете указать, следует ли блокировать GC:

GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized, blocking: true);

или

GC.Collect(GC.MaxGeneration, GCCollectionMode.Default, blocking: true);

GCCollectionMode.Default в настоящее время по умолчанию используется GCCollectionMode.Forced

Подробнее см.

MSDN: метод GC.Collect(Int32, GCCollectionMode, Boolean)

MSDN: Индуцированные коллекции - руководство

Ответ 3

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

Ответ 4

Вы должны просто предположить:

  • GC работает несколько раз, а не некоторые другие.
  • Тяжелые вещи происходят в некоторых несвязанных процессах несколько раз, а не в некоторых других.
  • Что-то сумасшедшее происходит время от времени.

И, следовательно, сделайте несколько итераций тестов, которые вы делаете, удалите самые высокие и самые низкие (предположите, что они были флюки в любом случае), и в среднем, что осталось. Это даст вам значимые сравнения.

Ответ 5

Способ GC в .Net работает, чтобы остановить все потоки (по крайней мере, для части полной коллекции, что и есть GC.Collect()). Поэтому вы можете сказать, что он очень синхронный, он не блокирует только один поток, но все они. И вызов GC.Collect() будет выполнять сбор и возврат только после его завершения, поэтому GC.Collect() - это способ запускать его синхронно.

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

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

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