Подтвердить что ты не робот

Python: статистика использования памяти для каждого типа объекта (или строки исходного кода)

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

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

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

Могу ли я получить некоторую статистику, как это? Или как я отлаживаю это?


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

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

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