在python中查找对对象的所有引用

在python中查找对对象的所有引用,python,django,memory-leaks,garbage-collection,Python,Django,Memory Leaks,Garbage Collection,在python中查找对象的所有引用的好方法是什么? 我问这个问题的原因是,看起来我们有一个“内存泄漏”。我们正在从web浏览器将图像文件上载到服务器。每次我们这样做时,服务器上的内存使用量都会与刚刚上传的文件大小成比例地增加。python垃圾收集永远不会释放这些内存,因此我认为可能存在指向未被删除或超出范围的图像数据的零散引用,即使在每个请求结束时也是如此 我想如果能够问python:“哪些引用仍然指向这个内存?”会很好,这样我就可以找出是什么阻止了垃圾收集释放它 目前,我们正在Heroku服务

在python中查找对象的所有引用的好方法是什么?

我问这个问题的原因是,看起来我们有一个“内存泄漏”。我们正在从web浏览器将图像文件上载到服务器。每次我们这样做时,服务器上的内存使用量都会与刚刚上传的文件大小成比例地增加。python垃圾收集永远不会释放这些内存,因此我认为可能存在指向未被删除或超出范围的图像数据的零散引用,即使在每个请求结束时也是如此

我想如果能够问python:“哪些引用仍然指向这个内存?”会很好,这样我就可以找出是什么阻止了垃圾收集释放它


目前,我们正在Heroku服务器上运行Python和Django。

Python的标准库具有包含垃圾收集器API的
gc
模块。您可能想要的功能之一是

gc.get_objects()
此函数返回垃圾收集器当前跟踪的所有对象的列表。下一步是分析它

如果您知道要跟踪的对象,可以使用
sys
模块的
getrefcount
功能:

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

Python的
gc
模块有几个有用的函数,但听起来像是您正在寻找的。下面是一个例子:

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


在我的简短实验中,我发现结果并不总是如此清晰。例如,内部字符串和元组的引用比您预期的要多。

您看过这个吗:sys.getrefcount()很有用,但是有没有办法看到这些引用是什么?其中的内容是:Python使用引用计数进行内存管理。这意味着在Python中创建的对象具有一个引用计数变量,该变量跟踪指向该对象的引用数。当该计数为零时,对象占用的内存被释放。[…]演示引用计数工作原理的简短代码示例:>>>导入sys>>>a=[]>>>b=a>>>sys.getrefcount(a)3[查看下一条注释][…继续上述注释]在上述示例中,空列表对象[]的引用计数为3。列表对象被a、b引用,参数被传递到sys.getrefcount()。这似乎是最简单也是最好的答案。。。。实际上是“答案”。