36

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

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

我认为能够问 python 会很好:“哪些引用仍然指向这个内存?” 这样我就可以弄清楚是什么阻止了垃圾收集器释放它。

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

4

2 回答 2

80

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

可以看到第一行是land d,第二行是 just l

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

于 2015-10-28T18:12:01.337 回答
10

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

gc.get_objects()

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

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

>>> x = object()
>>> sys.getrefcount(x)
2
>>> y = x
>>> sys.getrefcount(x)
3
于 2012-08-09T21:02:28.850 回答