Python:按对象类型(或源代码行)统计内存使用情况
我在用Python做一些复杂的计算(使用OpenCV和Numpy),结果发现内存使用量很大(超过1GB),而我最后只应该得到一个几MB的结果。
为了找出问题所在,我希望能有一些统计数据,告诉我每种类型的对象实例有多少,并按它们占用的总内存量排序(按对象类别)。
更好的是,如果能按源代码行来显示对象创建的情况就更好了(不过我猜这信息可能不可用,除非我在Python中开启一些调试功能,但那样会让计算变得很慢,所以我不确定这样是否有帮助)。
我能以某种方式得到这样的统计数据吗?或者我该如何调试这个问题呢?
有些人误解了我的意思:我只需要知道如何调试内存使用情况。处理/运行时间是可以接受的。
2 个回答
7
好的,我找到问题了。因为没有一个Python的内存分析工具能给出有用的结果(因为它们找不到内存),我很确定一些外部库(比如OpenCV)是内存泄漏的源头。
我用这段简单的代码可以重现内存泄漏:
import cv
while True: cv.CreateHist([40], cv.CV_HIST_ARRAY, [[0,255]], 1)
还有一些关于Python内存调试的其他资源,虽然在这个案例中没帮上忙,但可能对其他人有用:
11
我觉得你是在找一个Python的性能分析工具;
你可以用很多种工具,比如Heapy、profile或cprofile、Pysize等等……
使用Heapy的例子:
你需要在代码的某个地方加上这段代码:
from guppy import hpy
h = hpy()
print h.heap()
然后它会给你输出:
Partition of a set of 132527 objects. Total size = 8301532 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 35144 27 2140412 26 2140412 26 str
1 38397 29 1309020 16 3449432 42 tuple
2 530 0 739856 9 4189288 50 dict (no owner)
使用cprofile的例子:
你可以这样运行它:
python -m cProfile script.py
输出结果:
5 function calls in 0.000 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 myscript.py:1(<module>)
1 0.000 0.000 0.000 0.000 {execfile}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {range}
你还可以使用gc模块,来了解为什么Python没有释放你的内存,并且可以用gc.collect()来请求它释放内存。
顺便问一下,你有没有看过numpy,我觉得如果你在做复杂计算的话,它会更合适。