Python: статистика использования памяти для каждого типа объекта (или строки исходного кода)
Я делаю некоторые тяжелые вычисления с Python (используя OpenCV и Numpy), и в конце концов, я получаю много использования памяти ( > 1 ГБ), в результате чего все ссылки должны быть удалены, и у меня есть только конечный результат ( который не должен превышать нескольких МБ).
Чтобы отладить это, было бы неплохо, если бы я мог каким-то образом получить статистику, которая покажет мне, сколько экземпляров экземпляра существует из того типа, который упорядочен по общему объему памяти, который они берут (по классу объекта).
Или даже приятнее: не для класса объекта, а для строки исходного кода, где был создан объект (где, как я полагаю, эта информация недоступна, если я не активирую некоторую отладку в Python, что сделало бы вычисление слишком медленным, поэтому я не уверен если это было бы полезно).
Могу ли я получить некоторую статистику, как это? Или как я отлаживаю это?
Некоторые из них не поняли меня: мне нужно только знать, как отлаживать использование памяти. Обработка/время выполнения идеально.
Ответы
Ответ 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, которые были весьма интересными (в этом случае не помогли, но могут быть полезны для других):