У объекта Python нет ссылок, но он все еще доступен по слабой ссылке? - PullRequest
3 голосов
/ 15 июля 2009

Может ли gc.get_referrers (obj) вернуть пустой список для объекта, но объект по-прежнему будет доступен по слабой ссылке?

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

Редактировать: я не уверен, как именно пример кода поможет в этом случае - где-то явно есть сильная ссылка, но я буду проклят, если смогу его найти У меня сложилось впечатление, что get_referrers () идентифицирует все сильные ссылки на объект.

Редактировать: Решено . Я нашел переменную с сильной ссылкой - она ​​была внутри цикла событий игры, но не являлась переменной класса, поэтому get_referrers не брал ее.

Ответы [ 5 ]

1 голос
/ 04 ноября 2010

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

Разрешено, чтобы объект не имел ссылок, но не собирал мусор.

Из руководства по Python 2.7: «Реализация может отложить сборку мусора или вообще отказаться от нее - вопрос качества реализации заключается в том, как реализована сборка мусора, если не собраны объекты, которые еще доступны». 1005 *

Сборщик мусора NO-OP является законным.

Дискуссии о сборщиках мусора по поколениям и подсчету ссылок относятся к конкретной реализации CPython (как отмечено в вопросе)

1 голос
/ 15 июля 2009

Может также случиться, что ссылка была пропущена ошибочным расширением C, ИМХО, вы не увидите реферера, но все же рефконтр не падает до 0. Вы можете проверить возвращаемое значение sys.getrefcount.

1 голос
/ 15 июля 2009

Да: http://docs.python.org/library/weakref.html

Слабая ссылка не поддержит объект в живых.

Функция get_referrers () найдет только те контейнеры, которые поддерживают сборку мусора; типы расширений, которые ссылаются на другие объекты, но не поддерживают сборку мусора, не будут найдены.

Что заставляет вас думать, что объект не собирается? Кроме того, вы пробовали gc.collect ()?

0 голосов
/ 15 июля 2009

Если у вас есть сильная ссылка на объект, используйте gc.get_referrers (obj), чтобы найти его.

Это может помочь, если у вас есть утечка и вы не знаете, что течет:

http://mg.pov.lt/objgraph.py http://mg.pov.lt/blog/hunting-python-memleaks http://mg.pov.lt/blog/python-object-graphs.html

Это тонкая обертка вокруг проверяющего модуля; это может очень помочь, если у вас есть трудно отследить нежелательные ссылки. Для простого отслеживания ссылки, однако, gc.get_referrers - это, вероятно, все, что вам нужно.

0 голосов
/ 15 июля 2009

Как говорит Кристофер , слабая ссылка не учитывается при пересчете объекта и поэтому не может помешать Python удалить объект.

Однако сборщик мусора Python не удаляетобъекты, которые находятся в циклической ссылке и имеют определенный метод __del__.
Вы можете проверить (и исправить) такую ​​ситуацию, используя gc.garbage .

...