Найти все ссылки на объект в Python
Что такое хороший способ найти все ссылки на объект в Python?
Причина, по которой я спрашиваю, заключается в том, что, похоже, у нас "утечка памяти". Мы загружаем файлы изображений на сервер из веб-браузера. Каждый раз, когда мы делаем это, использование памяти на сервере увеличивается пропорционально размеру только что загруженного файла. Эта память никогда не освобождается сборщиком мусора в Python, поэтому я думаю, что, возможно, существуют случайные ссылки, указывающие на данные изображения, которые не удаляются и не выходят из области действия, даже в конце каждого запроса.
Я полагаю, было бы неплохо иметь возможность спросить python: "Какие ссылки все еще указывают на эту память?" так что я могу понять, что мешает сборщику мусора освободить его.
В настоящее время мы запускаем Python и Django на сервере Heroku.
Любые предложения и идеи приветствуются, спасибо большое!
2 ответа
Стандартная библиотека Python имеет gc
модуль, содержащий API сборщика мусора. Одна из функций, которую вы можете захотеть
gc.get_objects()
Эта функция возвращает список всех объектов, отслеживаемых в данный момент сборщиком мусора. Следующим шагом является его анализ.
Если вы знаете объект, который хотите отслеживать, вы можете использовать sys
модуля getrefcount
функция:
>>> x = object()
>>> sys.getrefcount(x)
2
>>> y = x
>>> sys.getrefcount(x)
3
Питона gc
Модуль имеет несколько полезных функций, но звучит как gc.get_referrers()
это то, что вы ищете. Вот пример:
import gc
def foo():
a = [2, 4, 6]
b = [1, 4, 7]
l = [a, b]
d = dict(a=a)
return l, d
l, d = foo()
r1 = gc.get_referrers(l[0])
r2 = gc.get_referrers(l[1])
print r1
print r2
Когда я запускаю это, я вижу следующий вывод:
[[[2, 4, 6], [1, 4, 7]], {'a': [2, 4, 6]}]
[[[2, 4, 6], [1, 4, 7]]]
Вы можете видеть, что первая строка l
а также d
и вторая строка просто l
,
В своих коротких экспериментах я обнаружил, что результаты не всегда такие чистые. Например, у внутренних строк и кортежей есть больше ссылок, чем вы ожидаете.