Как сборка мусора в Python работает с методами класса? - PullRequest
3 голосов
/ 09 мая 2009
class example:

    def exampleMethod(self):
        aVar = 'some string'
        return aVar

В этом примере, как работает сборка мусора после каждого вызова example.exampleMethod ()? Будет ли aVar освобожден после возвращения метода?

Ответы [ 4 ]

6 голосов
/ 09 мая 2009

Переменная никогда не освобождается.

Объект (в данном случае строка со значением 'some string' используется снова и снова, поэтому объект никогда не может быть освобожден.

Объекты освобождаются, когда переменная не ссылается на объект. Подумай об этом.

a = 'hi mom'
a = 'next value'

В этом случае на первый объект (строку со значением 'hi mom') больше не ссылаются нигде в скрипте при выполнении второго оператора. Объект ('hi mom') можно удалить из памяти.

4 голосов
/ 09 мая 2009

Каждый раз, когда вы назначаете объект переменной, вы увеличиваете счетчик ссылок этого объекта.

a = MyObject() # +1, so it's at 1
b = a # +1, so it's now 2
a = 'something else' # -1, so it's 1
b = 'something else' # -1, so it's 0

Никто не может получить доступ к этому объекту MyObject, который мы создали в первой строке.

Когда счетчик достигает нуля, сборщик мусора освобождает память.

Есть способ сделать сложную ссылку, которая не увеличивает счетчик ссылок (например, если вы не хотите, чтобы объект удерживался в памяти только потому, что он находится в некотором кеше).

Подробнее о подсчете ссылок cPython можно найти здесь .

Python - это язык, cPython - это (довольно популярная) реализация. Afaik сам язык не определяет как память освобождается.

3 голосов
/ 09 мая 2009

Из вашего примера, если вы вызываете example.exampleMethod (), не присваивая результаты (например, a = example.exampleMethod()), тогда он будет немедленно освобожден (в CPython), так как CPython использует механизм подсчета ссылок. Строки не очень хороший пример для использования, потому что они также имеют ряд оптимизаций, специфичных для реализации. Строки можно кэшировать и не освобождать, чтобы их можно было использовать повторно. Это особенно полезно, потому что строки очень часто используются в качестве ключей в словах.

Опять же, сборка мусора специфична для реализаций, поэтому CPython, Jython и IronPython будут вести себя по-разному, большинство из них описано на соответствующих сайтах / manual / code / etc. Если вы хотите немного разобраться, я бы предложил создать класс, в котором вы определили метод del (), который будет вызываться для объекта, подлежащего сборке мусора (это деструктор). Заставьте его напечатать что-нибудь, чтобы вы могли отследить его вызов:)

0 голосов
/ 09 мая 2009

Как и в ответе Нико, это зависит от того, что вы делаете с результатом, возвращенным exampleMethod. Python (или CPython в любом случае) использует подсчет ссылок. Во время метода aVar ссылается на строку, в то время как после этого переменная aVar удаляется, что может не оставить ссылок, в этом случае она удаляется.

Ниже приведен пример с пользовательским классом, имеющим деструктор ( del (self), который выводит «Уничтожаемый объект 1» или аналогичный. Gc - это модуль сборки мусора, который автоматически удаляет объекты с числом ссылок 0. Это для удобства, так как в противном случае нет никакой гарантии, когда сборщик мусора запущен.

import gc
class Noisy(object):
    def __init__(self, n):
        self.n = n
    def __del__(self):
        print "Object " + str(self.n) + " being destructed"     
class example(object):
    def exampleMethod(self, n):
        aVar = Noisy(n)
        return aVar
a = example()
a.exampleMethod(1)
b = a.exampleMethod(2)
gc.collect()
print "Before b is deleted"
del b
gc.collect()
print "After b is deleted"

Результат должен быть следующим:

Object 1 being destructed
While b lives
Object 2 being destructed
After b is deleted

Обратите внимание, что первый объект Noisy удаляется после возврата метода, так как он не присвоен переменной, поэтому имеет счетчик ссылок 0, но второй удаляется только после удаления переменной b, оставляя счетчик ссылок 0.

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