Python:按对象类型(或源代码行)统计内存使用情况

15 投票
2 回答
9796 浏览
提问于 2025-04-16 07:03

我在用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的性能分析工具;

你可以用很多种工具,比如Heapyprofile或cprofilePysize等等……

使用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,我觉得如果你在做复杂计算的话,它会更合适。

撰写回答