GC.Collect в цикле? - PullRequest
       31

GC.Collect в цикле?

21 голосов
/ 17 марта 2009

Я нашел этот фрагмент кода внутри System.Web.ISAPIRuntime, используя Reflector

public void DoGCCollect()
{
    for (int i = 10; i > 0; i--)
    {
        GC.Collect();
    }
}

Может кто-нибудь прокомментировать это? Есть ли причина делать GC.Collect () в цикле? Почему 10 раз, а не 3, 5 или 20? Анализ показал, что он не используется внутри .net framework, но общедоступен, поэтому я полагаю, что IIS может вызвать его ...

редактировать:

Просто для уточнения: я никогда не звонил в GC.Collect и не собираюсь его использовать. Я знаю, что это плохая идея в большинстве (если не во всех) случаях. Вопрос в том, почему .net framework это делает. Спасибо за все ваши ответы.

Ответы [ 8 ]

14 голосов
/ 17 марта 2009

Да, это ужасно. Во-первых, вам вообще не нужно это делать. Однако, если вы действительно хотите принудительно собрать сборку мусора и дождаться ее завершения, вам, вероятно, следует использовать:

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
// Collect anything that's just been finalized
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

Правда, не очень хорошая идея.

7 голосов
/ 17 марта 2009

выглядит действительно ужасно:)

5 голосов
/ 17 марта 2009

Я не думаю, что вы получите лучшее объяснение, что «один из программистов Microsoft довольно невежественен, и, очевидно, никто больше не удосужился взглянуть на его код до того, как он будет зарегистрирован». ;)

Хотя это выглядит страшно.

Это довольно распространенный ответ на ошибки, которые вы не понимаете. По какой-то причине вы пытаетесь вызвать GC, и каким-то образом его вызов не решает вашу проблему (возможно, настоящая проблема заключалась в том, что вам нужно дождаться потока финализатора или чего-то еще), поэтому наивное решение очевидно, «тогда я просто продолжу называть это».

Аналогично повторному нажатию кнопки «печать» до печати документа.

Возможно, вам следует отправить его на thedailywtf.com.

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

Мне очень нравится реализация этого метода в Mono:

public void DoGCCollect ()
{
  // Do nothing.
}

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

1 голос
/ 17 марта 2009

Не следует ли указывать на подобные вещи в Microsoft? Будет ли полезно опубликовать это на сайте Connect?

1 голос
/ 17 марта 2009

Похоже, что кто-то с комплексом Судного Дня написал это с коннотацией, что он заканчивает мир 10-секундным таймером ...

0 голосов
/ 17 марта 2009

Прежде всего, не стоит называть GC.Collect(). Многократное обращение к нему мало что дает.

Однако иногда вы видите схему вызова Collect(), затем WaitForPendingFinalizers() и, наконец, Collect() снова. Идея заключается в том, чтобы гарантировать, что экземпляры с финализаторами также будут возвращены, так как они выживут в первой коллекции. Имейте в виду, что это приведет к задержке приложения, и это очень редко потребуется.

0 голосов
/ 17 марта 2009

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

99,9% времени, когда вам никогда не нужно звонить в GC из вашего кода.

...