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

时间:2012-08-09 20:51:34

标签: python django memory-leaks garbage-collection

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

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

我认为能够问python会很高兴:“哪些引用仍然指向这个内存?”这样我就可以弄清楚是什么让垃圾收集免于它。

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

非常感谢任何建议和想法,非常感谢!

2 个答案:

答案 0 :(得分:29)

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]]]

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

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

答案 1 :(得分:10)

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

gc.get_objects()

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

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

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