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

可以看到第一行是ld,第二行正好是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中查找对对象的所有引用的主要内容,如果未能解决你的问题,请参考以下文章

Python 面向对象

Python引用的概念

python面试题

Python 深浅拷贝

如何理解Python中的容器对象

python的内存管理机制