关于django:在python中查找对对象的所有引用

Find all references to an object in python

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

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

我觉得能够问python:"还有什么引用指向这个内存?"这样我就可以搞清楚是什么阻止了垃圾收集的释放。

目前我们在Heroku服务器上运行python和django。

感谢您的建议和想法,非常感谢!


python的gc模块有几个有用的功能,但听起来像是gc.get_referrers()就是您要找的。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

当我运行它时,我看到以下输出:

1
2
[[[2, 4, 6], [1, 4, 7]], {'a': [2, 4, 6]}]
[[[2, 4, 6], [1, 4, 7]]]

你可以看到第一行是ld,第二行是l

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


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

1
gc.get_objects()

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

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

1
2
3
4
5
6
>>> x = object()
>>> sys.getrefcount(x)
2
>>> y = x
>>> sys.getrefcount(x)
3