谁占用了我的Python内存?
这是一个关于Python代码的通用问题。 我怎样才能有效地找到我的Python代码中最占内存的部分呢?
比如说,看看这个小例子:
def my_func():
a = [1] * (12 ** 4)
return a
def my_func2():
b = [2] * (10 ** 7)
return b
if __name__ == '__main__':
a1 = my_func()
a2 = my_func2()
我怎么才能自动化地判断a2的大小比a1大很多?
而且我怎么能自动化地追踪到my_func1()
和my_func2()
这两个函数呢?
如果是C/C++代码,我会使用valgrind --tool=massif
,它可以直接找到占用内存最多的部分,但对于Python,我需要你们的帮助。
Meliae似乎能提供一些答案,但效果远不如massif在C/C++中的表现好。
1 个回答
1
locals()(局部变量)和 globals()(全局变量)会返回一个字典,里面包含了所有当前存在的局部(或全局)对象。你可以这样使用它们:
import sys
sizes = dict((obj, sys.getsizeof(eval(obj))) for obj in locals().keys())
不过,这个方法有个缺点,就是它无法识别那些没有完全实现 __getsizeof__
的对象,比如 Numpy 数组或者引用。例如,如果你这样做:
print sys.getsizeof(a2)
sys.getsizeof(a1)
a2.append(a1)
print sys.getsizeof(a2)
输出结果会是:
40000036
82980
45000064 ---> The list is 60 times bigger!
当然,单单删除 a1 并不会释放它占用的 82 k,因为 a1 里还有一个引用。但我们可以让事情变得更加复杂:
a2 = my_func2()
print sys.getsizeof(a2)
a2.append(a2)
print sys.getsizeof(a2)
这时输出结果看起来会很熟悉:
40000036
45000064
其他工具可能会尝试解决这个问题,搜索引用树,但在 Python 中进行全面的内存分析这个问题依然没有解决。而且,当对象通过 C API 存储数据时,情况会更糟,这种情况在 Numpy 数组中就会发生。
不过,有一些工具在大多数实际情况下是“足够好的”。就像链接中提到的,Heapy 是一个非常不错的选择。