2015-01-16 2 views
1

Я пытаюсь переопределить (еще раз ... знаю ...) простую сеть на питоне, состоящую из классов узлов, которые ссылаются на другие классы узлов (дети-дети), и Мне было интересно, что произойдет, если я создам рекурсивную сеть (node1 -> node2 -> node3 -> node1) и случайно потеряю все ссылки на любой из узлов.Python: утечка памяти в классах любимых узлов

Представьте У меня есть следующий код

class node(): 
    def __init__(self): 
     self.children = [] 

    def append(self, child): 
     self.children.append(child) 

node1 = node() 
node2 = node() 

node1.append(node2) 
node2.append(node1) # now the network is recursive 

node1 = 0 
# node1 is still referenced in node2.children so will not be deleted 
node2 = 0 

# now both node1 and node2 are not directly referenced by any variable 
# but they are referenced by the two children instances 

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

Будет ли уничтожен узел1 и узел2?

ответ

0

Да, объекты будут собираться мусором. Сборщик мусора будет обнаруживать круговую ссылку и разбивать ее так, чтобы можно было провести обычную очистку подсчета ссылок. См. gc module.

Вы бы иметь проблемы, если ваш node класс реализован метод __del__ и вы используете версию Python < 3.4. В 3.4 теперь может break circular references involving instances with __del__ methods в большинстве случаев.

Из object.__del__ documentation:

Примечания: del x не непосредственно вызывать x.__del__() - бывший декремент счетчика ссылок для x один, а второй только называется, когда x «s счетчик ссылок достигает нуль. Некоторые распространенные ситуации, которые могут препятствовать отправке ссылочного счета объекта нулю, включают в себя: круглые ссылки между объектами (например, двусвязный список или древовидная структура данных с родительскими и дочерними указателями); ссылка на объект в кадре стека функции, которая поймала исключение (трассировка, хранящаяся в sys.exc_traceback, сохраняет фрейм стека); или ссылка на объект в фрейме стека, который вызвал необработанное исключение в интерактивном режиме (трассировка, хранящаяся в sys.last_traceback, сохраняет кадр стека живым). Первая ситуация может быть устранена только путем явного нарушения циклов; последние две ситуации могут быть решены путем хранения None в sys.exc_traceback или sys.last_traceback. Циркулярные ссылки, которые являются мусором, обнаруживаются, когда детектор цикла опциона включен (он включен по умолчанию), но может быть очищен только в том случае, если не задействованы методы на уровне Python __del__(). Обратитесь к документации модуля gc для получения дополнительной информации о том, как методы __del__() обрабатываются детектором цикла, в частности описание значения мусора.

+0

благодарит за информацию ... это было очень полезно! – ltrojan

Смежные вопросы