Подтвердить что ты не робот

Найти все ссылки на объект в python

Что такое хороший способ найти все ссылки на объект в Python?

Причина, по которой я спрашиваю, заключается в том, что, похоже, у нас "утечка памяти". Мы загружаем файлы изображений на сервер из веб-браузера. Каждый раз, когда мы делаем это, использование памяти на сервере увеличивается пропорционально размеру только что загруженного файла. Эта память никогда не освобождается сборщиком мусора в Python, поэтому я думаю, что, возможно, существуют случайные ссылки, указывающие на данные изображения, которые не удаляются или выходят из области действия даже в конце каждого запроса.

Я полагаю, было бы неплохо иметь возможность спросить python: "Какие ссылки все еще указывают на эту память?" так что я могу понять, что мешает сборщику мусора освободить его.

В настоящее время мы запускаем Python и Django на сервере Heroku.

4b9b3361

Ответ 1

Стандартная библиотека Python имеет модуль gc, содержащий API сборщика мусора. Одна из функций, которую вы хотите получить, -

gc.get_objects()

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

Если вы знаете объект, который хотите отслеживать, вы можете использовать функцию sys module getrefcount:

>>> x = object()
>>> sys.getrefcount(x)
2
>>> y = x
>>> sys.getrefcount(x)
3

Ответ 2

Модуль Python 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.

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