Зачем отключать сборщик мусора?

Pythons gc.disable отключает автоматическую сборку мусора. Насколько я понимаю, это будет иметь некоторые побочные эффекты. Почему кто-то хочет отключить автоматическую сборку мусора и как можно эффективно управлять памятью без нее?

Ответы

Ответ 1

Одним из способов отключения сборщика мусора является получение более согласованных результатов при синхронизации производительности кода. Модуль timeit делает это.

def timeit(self, number=default_number):
    if itertools:
        it = itertools.repeat(None, number)
    else:
        it = [None] * number
    gcold = gc.isenabled()
    gc.disable()
    ...

В Python2 и до Python3.2 gc.disable() также используется, чтобы избежать ошибки, вызванной сбором мусора между fork и exec. Проблема, похоже, была исправлена ​​в Python3.3 без вызова gc.disable().

Ответ 2

С той же страницы вы ссылаетесь на:

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

Итак, это отвечает на вторую часть вопроса: "Как можно эффективно управлять памятью без нее". Не создавайте ссылочные циклы. Это довольно ограниченный случай использования, конечно.

Для первой части вопроса ответ - это производительность. Опять же, довольно ограниченный вариант использования.

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

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

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

Ответ 3

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

Если вы хотите снова включить автоматический GC, или если вы предпочитаете делать это вручную, вызывая gc.collect(), это не касается этого вопроса.

Кроме того, некоторые программы предназначены для запуска только очень короткое время, так что, возможно, разработчик может гарантировать, что за это время не может возникнуть проблема с памятью (рассмотрите такие программы, как ls); то этим аспектом GC можно пренебречь в пользу производительности.

Ответ 4

Другим вариантом использования было бы вручную управлять сборкой мусора с помощью gc.collect()