Python: статистика использования памяти по типам объектов (или строка исходного кода) - PullRequest
12 голосов
/ 14 ноября 2010

Я делаю некоторые тяжелые вычисления с Python (используя OpenCV и Numpy), и в конце я получаю много использования памяти (> 1 ГБ), в результате чего все ссылки должны быть удалены, и у меня есть только конечный результат ( который не должен превышать нескольких МБ).

Для отладки было бы неплохо, если бы я мог как-то получить статистику, которая показывает мне, сколько существует экземпляров объектов того или иного типа, упорядоченных по общему количеству памяти, которое они занимают (на класс объектов).

Или даже лучше: не для класса объекта, а для строки исходного кода, в которой был создан объект (поэтому я полагаю, что эта информация недоступна, если я не активирую некоторую отладку в Python, которая сделает вычисления слишком медленными, поэтому я не уверен если это будет полезно).

Могу я как-нибудь получить такую ​​статистику? Или как бы отладить это?


Некоторые неправильно меня поняли: мне только нужно знать, как отладить использование памяти. Обработка / время выполнения идеально.

Ответы [ 2 ]

9 голосов
/ 14 ноября 2010

Я думаю, вы ищете профилировщик Python;

у вас есть куча из них, которые вы можете использовать, например, профиль Heapy , или 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 , я думаю, что это более удобно, если вы делаете тяжелые вычисления, как вы сказали.

6 голосов
/ 14 ноября 2010

Хорошо, я выследил это.Поскольку ни один из профилей mem Python не дает полезного вывода (потому что они не могут найти память), я был совершенно уверен, что некоторые внешние библиотеки (OpenCV) были источником утечки памяти.

ИЯ мог бы воспроизвести утечку mem с помощью этого простого кода:

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

Некоторые другие ресурсы для отладки памяти Python, которые были довольно интересными (не помогли в этом случае, но могут быть полезны для других):

...