GC.Collect () блокируется? - PullRequest
13 голосов
/ 19 июня 2011

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

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

Ответы [ 5 ]

11 голосов
/ 19 июня 2011

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

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

   GC.Collect();

   GC.WaitForPendingFinalizers();
10 голосов
/ 17 декабря 2014

Начиная с .NET Framework 4.5 вы можете указать, следует ли блокировать коллекцию GC: * ​​1003 *

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: Индуцированные коллекции - руководство

2 голосов
/ 19 июня 2011

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

  1. GC запускается несколько раз, а не некоторые другие.
  2. Тяжелые вещи случаются в некоторых не связанных процессах несколько раз, а не в некоторых других.
  3. Время от времени происходит что-то сумасшедшее.

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

2 голосов
/ 19 июня 2011

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

0 голосов
/ 19 июня 2011

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...