代码之家  ›  专栏  ›  技术社区  ›  Albert

Python:每个对象类型(或源代码行)的内存使用统计信息

  •  12
  • Albert  · 技术社区  · 14 年前

    我正在用Python做一些繁重的计算(使用OpenCV和Numpy),最后,我得到了大量的内存使用量(>1GB),所有的ref都应该消失,我只有最终结果(不应该超过几MB)。

    为了调试它,如果我能得到一些统计数据,以某种方式告诉我有多少类型的对象实例,按它们占用的内存总量排序(每个对象类)。

    或者更好:不是每个对象类,而是每个创建对象的源代码行(因此,我猜这些信息是不可用的,除非我在Python中激活一些调试,这会使计算太慢,所以我不确定这是否有用)。

    我能得到这样的数据吗?或者我该如何调试?


    有些人误解了我:我 只有 需要知道如何调试内存使用。处理/运行时是完美的。

    2 回复  |  直到 14 年前
        1
  •  9
  •   mouad    14 年前

    我想你在找一个python分析器;

    你有很多可以用的,比如 Heapy , profile or 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 ,如果你像你说的那样做繁重的计算,我觉得更合适。

        2
  •  6
  •   Albert    14 年前

    好吧,我找到了。由于没有一个Python mem概要文件提供任何有用的输出(因为它们找不到内存),我非常确定一些外部lib(OpenCV)是mem泄漏的根源。

    我可以用这个简单的代码重现mem泄漏:

    import cv
    while True: cv.CreateHist([40], cv.CV_HIST_ARRAY, [[0,255]], 1)
    

    Python mem调试的其他一些资源非常有趣(在这种情况下没有帮助,但可能对其他人有用):