Собирает ли Python-мусор переменные, на которые больше нет ссылок, пока они находятся в области действия функции? - PullRequest
0 голосов
/ 27 декабря 2018

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

Скажем, например, у меня есть такая функция:

def long_running_function():
   x = MemoryIntensiveObject()
   print id(x)
   # lots of hard work done here which does not reference x
   return

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

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

Или ответ проще: если мы все еще находимся в области, где он "может" использоваться, он не будет очищен?

1 Ответ

0 голосов
/ 27 декабря 2018

Нет, CPython не будет собирать объект мусором, пока имя, которое ссылается на этот объект, все еще определено в текущей области.

Это потому, что даже если нет ссылок на имя x как литералы в коде, вызовы vars() или locals() могут по-прежнему захватывать копию словаря пространства имен localals (либо до, либо после последней ссылки на x), и, следовательно, все пространство имен localals эффективно "укореняет"значения, на которые он ссылается до тех пор, пока выполнение не выйдет из области видимости.

Я точно не знаю, как это делают другие реализации.В частности, в JIT-скомпилированной реализации, такой как PyPy, Jython или IronPython, теоретически возможно, что эта оптимизация будет выполнена.JITM и CLR JIT фактически выполняют эту оптимизацию на практике на других языках.Будет ли Python на этих платформах иметь возможность использовать преимущества или нет, полностью зависит от байт-кода, в который компилируется код Python.

...