Я хочу знать использование памяти моим приложением Python и, в частности, хочу знать, какие блоки / части кода или объекты потребляют больше всего памяти. Поиск Google показывает, что коммерческий - Валидатор памяти Python (только для Windows).
А с открытым исходным кодом - PySizer и Здоровенный.
Я никого не пробовал, поэтому хотел знать, какой из них лучше, учитывая:
Дает больше всего деталей.
Мне нужно внести в свой код минимум изменений или не вносить никаких изменений.
@MikeiLL Есть место для таких вопросов: Рекомендации по программному обеспечению
Это происходит достаточно часто, чтобы вместо этого мы могли перенести один вопрос на другой форум.
Один совет: если кто-то использует gae и хочет проверить использование памяти - это большая головная боль, потому что эти инструменты ничего не выводили или событие не запускалось. Если вы хотите протестировать что-то маленькое, переместите функцию, которую вы хотите протестировать, в отдельный файл и запустите этот файл отдельно.
Рекомендую прыщ






Рекомендую Лозоискатель. Его очень легко настроить, и вам не нужно ничего менять в коде. Вы можете просматривать количество объектов каждого типа во времени, просматривать список живых объектов, просматривать ссылки на живые объекты - и все это с помощью простого веб-интерфейса.
# memdebug.py
import cherrypy
import dowser
def start(port):
cherrypy.tree.mount(dowser.Root())
cherrypy.config.update({
'environment': 'embedded',
'server.socket_port': port
})
cherrypy.server.quickstart()
cherrypy.engine.start(blocking=False)
Вы импортируете memdebug и вызываете memdebug.start. Это все.
Я не пробовал PySizer или Heapy. Буду признателен за отзывы других.
ОБНОВИТЬ
Приведенный выше код предназначен для CherryPy 2.X, CherryPy 3.X, метод server.quickstart был удален, а engine.start не принимает флаг blocking. Итак, если вы используете CherryPy 3.X
# memdebug.py
import cherrypy
import dowser
def start(port):
cherrypy.tree.mount(dowser.Root())
cherrypy.config.update({
'environment': 'embedded',
'server.socket_port': port
})
cherrypy.engine.start()
но это только для cherrypy, как использовать его с помощью простого скрипта?
Это не для CherryPy. Думайте о CherryPy как о наборе инструментов с графическим интерфейсом.
fwiw, страница pysizer pysizer.8325.org, кажется, рекомендует heapy, который, по его словам, похож на
Похоже, что приведенный выше код предназначен для использования с CherryPy 2.x. Для CherryPy 3.x удалите blocking=False из вызова cherrypy.engine.start().
Существует общий порт WSGI Dowser под названием Dozer, который вы также можете использовать с другими веб-серверами: pypi.python.org/pypi/Dozer
Cherrypy 3.1 удалил cherrypy.server.quickstart (), поэтому просто используйте cherrypy.engine.start ()
Я люблю и использую лозоискатель, но проблема для меня в том, что приложение, в котором я его использую, дает вам около 1000 графиков, и становится больно находить то, что важно, и после того, как вы это сделаете, у болевой точки может быть так много графиков что страница трассировки даже не загружается должным образом. Так что он не очень хорошо масштабируется.
Похоже, aminus.net больше не существует. Некоторый быстрый поиск в Интернете нашел ссылки на него, которые только указали, что он существует на сайтах aminus.net. Сообщение Anaconda Prompt conda search dowser ничего не нашло. Я бы сделал вывод, что Dowser больше не является легкодоступным и, конечно же, не поддерживается.
это не работает в python 3. Я получаю очевидную ошибку StringIO.
гуппи3 довольно прост в использовании. В какой-то момент вашего кода вы должны написать следующее:
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)
Вы также можете узнать, откуда ссылаются на объекты, и получить статистику по этому поводу, но почему-то документация по этому поводу немного скудна.
Также есть графический браузер, написанный на Tk.
Для Python 2.x используйте Здоровенный.
к сожалению, похоже, что он не собирается и не устанавливается в OSX .. 10.4 по крайней мере.
Он основан на OS X 10.7.1 с домашним пивом, но, к сожалению, не работает :-(
Если вы используете Python 2.7, вам может понадобиться его магистральная версия: sourceforge.net/tracker/…, pip install https://guppy-pe.svn.sourceforge.net/svnroot/guppy-pe/trunk/guppy.
Последняя версия (0.1.9) построена на Windows для Python 2.6 x64, но вызов h.heap() вызывает APPCRASH.
Куча документов ... нехорошо. Но я нашел этот пост в блоге очень полезным для начала: smira.ru/wp-content/uploads/2011/08/heapy.html
Heapy - это, безусловно, самый простой профилировщик кучи для запуска при подключении к текущему процессу python с помощью rfoo, он отлично работает в многопоточном приложении и отлично работает с pip с помощью «pip install guppy». Обычно работает представление по умолчанию, но hpy предлагает несколько представлений данные профиля, включая показ вашего использования, рассчитываются по ссылке. Сообщение в блоге, на которое ссылается @JoeShaw, очень полезно.
Обратите внимание, что heapy не включает память, выделенную в расширениях python. Если кто-нибудь разработал механизм, позволяющий включать объекты boost::python, было бы неплохо увидеть несколько примеров!
По состоянию на 06.07.2014 гуппи не поддерживает Python 3.
@JamesSnyder Похоже, что обычная версия pip (1.10) теперь работает с python 2.7
Просто установил нормально с помощью pip (python 2.7). Я обнаружил, что проблема, для которой я хотел его использовать (использование памяти постоянно увеличивается), исчезает, когда я вызываю h.heap (). Есть идеи, почему это может быть?
Как узнать, что str потребляет больше всего памяти, и как это полезно? Это может быть одна из миллиона точек кода. Не зная, куда делаются эти звонки, предоставленная здесь информация бесполезна.
Существует форк guppy, который поддерживает Python 3, и называется guppy3.
Куда вставить этот код pofiler в наш существующий код Python? Это должно быть в конце / начале? Как нам интегрировать этот код профилировщика в наш существующий код для статистики использования ресурсов?
Рассмотрим библиотеку objgraph (см. это сообщение в блоге для примера использования).
objgraph помог мне решить проблему утечки памяти, с которой я столкнулся сегодня. objgraph.show_growth () был особенно полезен
Я тоже нашел objgraph действительно полезным. Вы можете сделать такие вещи, как objgraph.by_type('dict'), чтобы понять, откуда берутся все эти неожиданные объекты dict.
Мой модуль memory_profiler способен распечатывать построчные отчеты об использовании памяти и работает в Unix и Windows (для последнего требуется psutil). Вывод не очень подробный, но цель состоит в том, чтобы дать вам обзор того, где код потребляет больше памяти, а не исчерпывающий анализ выделенных объектов.
После украшения вашей функции с помощью @profile и запуска вашего кода с флагом -m memory_profiler он напечатает построчный отчет, подобный этому:
Line # Mem usage Increment Line Contents
==============================================
3 @profile
4 5.97 MB 0.00 MB def my_func():
5 13.61 MB 7.64 MB a = [1] * (10 ** 6)
6 166.20 MB 152.59 MB b = [2] * (2 * 10 ** 7)
7 13.61 MB -152.59 MB del b
8 13.61 MB 0.00 MB return a
Для моего варианта использования - простого сценария манипулирования изображениями, а не сложной системы, в которой некоторые курсоры оставались открытыми - это было лучшим решением. Очень просто зайти и понять, что происходит, с минимальным добавлением мусора в ваш код. Идеально подходит для быстрых исправлений и, вероятно, отлично подходит для других приложений.
Это здорово. Есть ли способ использовать его для сбора данных об использовании памяти для каждого объекта? (в отличие от строки). В идеале из сеанса IPython с объектами, уже находящимися в памяти. Если нет, есть ли у вас какие-нибудь указатели на что-то в этом роде?
Он не использует память для отдельных объектов. Для этой задачи вам может понадобиться гуппи / куча.
Я считаю, что memory_profiler действительно прост и удобен в использовании. Я хочу выполнять профилирование по строке, а не по объекту. Спасибо за письмо.
@FabianPedregosa, как доза memory_profiler обрабатывает циклы, может ли он идентифицировать номер итерации цикла?
Он идентифицирует циклы только неявно, когда он пытается сообщить количество построчно и находит повторяющиеся строки. В этом случае потребуется максимум всех итераций.
Я попытался профилировать использование памяти приложением python, которое использовало tensorflow в режиме процессора, в зависимости от размера входного изображения, и python -m memory_profiler example.py не дает мне правильных результатов, а mprof дает мне результаты, аналогичные htop.
Не очень хорошо работает в программах с интенсивным использованием ЦП
@FabianPedregosa: Как указать путь установки? Я хочу установить его в другую папку Python. Спасибо
Как и любой другой пакет Python, pip install --target=/custom/path memory_profiler
Я пробовал memory_profiler, но считаю, что это не лучший выбор. Это делает выполнение программы невероятно медленным (примерно в 30 раз медленнее).
Существуют постоянные накладные расходы (на каждую строку) при отслеживании потребления памяти, поэтому, если ваша программа очень длинная или имеет много быстрых циклов for / while, я ожидаю, что это значительно замедлит вашу программу. В этом случае может быть лучше профилировщик на основе времени (в отличие от линейного). Он запускается как mprof run <script>, дополнительную информацию см. В документации.
профилировщик памяти и heapy решают 2 разных случая, я думаю, один связан с потреблением памяти на строку, а другой - с объектами
@FabianPedregosa Буферизирует ли memory_profiler свой вывод? Возможно, я делаю что-то не так, но кажется, что вместо того, чтобы сбрасывать профиль для функции после ее завершения, он ждет завершения скрипта.
Он действительно ждет завершения сценария. В противном случае сделать это будет непросто, так как функцию можно будет вызвать снова, и в этом случае memory_profiler будет агрегировать результаты.
@FabianPedregosa Спасибо за такую полезную и простую библиотеку! Хотя меня путает вывод - когда я запускаю mprof run test.py, а затем mprof plot, я получаю разное использование памяти при построчном выводе и со временем. Построчно я получаю максимум 550 МБ, в то время как из графика я получаю максимум 5000 МБ. В чем может быть проблема? Спасибо!
Для меня профилировщик памяти замедлил выполнение примерно в 10 раз! Обратите внимание, что у меня были большие объекты порядка нескольких ГБ. В противном случае крутой инструмент.
Маппи - это (еще один) профилировщик использования памяти для Python. Основное внимание в этом наборе инструментов уделяется выявлению утечек памяти.
Muppy пытается помочь разработчикам выявить утечки памяти в приложениях Python. Это позволяет отслеживать использование памяти во время выполнения и выявлять утечки объектов. Дополнительно предусмотрены инструменты, позволяющие определить источник невыпущенных объектов.
Я разрабатываю профилировщик памяти для Python под названием memprof:
http://jmdana.github.io/memprof/
Это позволяет вам регистрировать и отображать использование памяти вашими переменными во время выполнения декорированных методов. Вам просто нужно импортировать библиотеку, используя:
from memprof import memprof
И украсьте свой метод, используя:
@memprof
Это пример того, как выглядят графики:

Проект размещен в GitHub:
https://github.com/jmdana/memprof
Как мне его использовать? Что такое а, б, в?
@ tommy.carstensen a, b и c - имена переменных. Вы можете найти документацию на github.com/jmdana/memprof. Если у вас есть какие-либо вопросы, пожалуйста, отправьте сообщение о проблеме в github или отправьте электронное письмо в список рассылки, который можно найти в документации.
Попробуйте также проект pytracemalloc, который обеспечивает использование памяти для каждого номера строки Python.
РЕДАКТИРОВАТЬ (2014/04): теперь у него есть графический интерфейс Qt для анализа снимков.
tracemalloc теперь является частью стандартной библиотеки Python. См. docs.python.org/3/library/tracemalloc.html
Для поиска источников утечек рекомендую objgraph.