在python中查找对对象的所有引用
Posted
技术标签:
【中文标题】在python中查找对对象的所有引用【英文标题】:Find all references to an object in python 【发布时间】:2012-08-07 04:05:58 【问题描述】:在 python 中查找对象的所有引用的好方法是什么?
我问的原因是看起来我们有“内存泄漏”。我们正在从 Web 浏览器将图像文件上传到服务器。每次我们这样做时,服务器上的内存使用量与刚刚上传的文件的大小成正比。这个内存永远不会被python垃圾收集释放,所以我认为可能有指向图像数据的杂散引用没有被删除或超出范围,即使在每个请求结束时也是如此。
我认为能够问 python 会很好:“哪些引用仍然指向这个内存?”这样我就可以弄清楚是什么阻止了垃圾收集器释放它。
目前我们在 Heroku 服务器上运行 Python 和 Django。
【问题讨论】:
***.com/questions/1339293/… 你看过这个吗:***.com/questions/110259/python-memory-profiler 【参考方案1】: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
。
在我的简短实验中,我发现结果并不总是那么干净。例如,Interned 字符串和元组的引用者比您预期的要多。
【讨论】:
这似乎是最简单和最好的答案。 ...实际上是“一个答案”。【参考方案2】:Python 的标准库有 gc
包含垃圾收集器 API 的模块。您可能想要的功能之一是
gc.get_objects()
此函数返回垃圾收集器当前跟踪的所有对象的列表。下一步是对其进行分析。
如果您知道要跟踪的对象,可以使用sys
模块的getrefcount
函数:
>>> x = object()
>>> sys.getrefcount(x)
2
>>> y = x
>>> sys.getrefcount(x)
3
【讨论】:
sys.getrefcount() 很有用,但是有什么方法可以查看这些引用是什么? realpython.com/python-gil 中写道:Python 使用引用计数进行内存管理。这意味着在 Python 中创建的对象有一个引用计数变量,该变量跟踪指向该对象的引用数量。当这个计数达到零时,对象占用的内存被释放。 [...]演示引用计数如何工作的简短代码示例: >>> import sys >>> a = [] >>> b = a >>> sys.getrefcount(a) 3 [查看下一条评论] [...continuation of the above comment] 在上面的例子中,空列表对象 [] 的引用计数为 3。列表对象被 a、b 引用,参数传递给sys.getrefcount().以上是关于在python中查找对对象的所有引用的主要内容,如果未能解决你的问题,请参考以下文章