¿Qué perfil de memoria Python se recomienda? [cerrado]

671

Quiero saber el uso de memoria de mi aplicación Python y específicamente quiero saber qué bloques de código / porciones u objetos consumen más memoria. La búsqueda de Google muestra que uno comercial es Python Memory Validator (solo Windows).

Y los de código abierto son PySizer y Heapy .

No he probado a nadie, así que quería saber cuál es el mejor teniendo en cuenta:

  1. Da la mayoría de los detalles.

  2. Tengo que hacer menos o ningún cambio en mi código.

Anurag Uniyal
fuente
2
Para encontrar las fuentes de las fugas, recomiendo objgraph.
pi.
99
@MikeiLL Hay un lugar para preguntas como estas: Recomendaciones de software
Poik
2
Esto sucede con la frecuencia suficiente para que podamos migrar una pregunta a otro foro.
zabumba
Un consejo: si alguien usa gae to y quiere verificar el uso de la memoria, es un gran dolor de cabeza, porque esas herramientas no produjeron nada o el evento no se inició. Si desea probar algo pequeño, mueva la función que desea probar para separar el archivo y ejecute este archivo solo.
alexche8
44
Recomiendo pympler
zzzeek

Respuestas:

288

Heapy es bastante simple de usar. En algún momento de su código, debe escribir lo siguiente:

from guppy import hpy
h = hpy()
print(h.heap())

Esto le da un resultado como este:

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)

También puede averiguar desde dónde se hace referencia a los objetos y obtener estadísticas al respecto, pero de alguna manera los documentos son un poco escasos.

También hay un navegador gráfico, escrito en Tk.

Torsten Marek
fuente
24
Si estás en Python 2.7, es posible que necesites la versión troncal del mismo: sourceforge.net/tracker/… ,pip install https://guppy-pe.svn.sourceforge.net/svnroot/guppy-pe/trunk/guppy
James Snyder
27
Los documentos pesados ​​son ... no buenos. Pero esta publicación del blog me pareció muy útil para comenzar: smira.ru/wp-content/uploads/2011/08/heapy.html
Joe Shaw
44
Tenga en cuenta que heapy no incluye memoria asignada en extensiones de python. Si alguien ha ideado un mecanismo para engordar para incluir boost::pythonobjetos, ¡sería bueno ver algunos ejemplos!
amos
34
A partir del 2014-07-06, guppy no es compatible con Python 3.
Quentin Pradet
55
Hay una bifurcación de guppy que admite Python 3 llamada guppy3.
David Foster
385

Como nadie lo ha mencionado, señalaré mi módulo memory_profiler, que es capaz de imprimir informes línea por línea del uso de memoria y funciona en Unix y Windows (necesita psutil en este último). La salida no es muy detallada, pero el objetivo es darle una visión general de dónde el código consume más memoria y no un análisis exhaustivo de los objetos asignados.

Después de decorar su función @profiley ejecutar su código con la -m memory_profilerbandera, imprimirá un informe línea por línea como este:

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
Fabian Pedregosa
fuente
1
Para mi caso de uso, un simple script de manipulación de imágenes, no un sistema complejo, que dejó algunos cursores abiertos, esta fue la mejor solución. Muy fácil de ingresar y descubrir qué está sucediendo, con un mínimo de suciedad agregada a su código. Perfecto para soluciones rápidas y probablemente también excelente para otras aplicaciones.
driftcatcher
10
Me parece que memory_profiler es realmente simple y fácil de usar. Quiero hacer perfiles por línea y no por objeto. Gracias por escribir.
tommy.carstensen
1
@FabianPedregosa ¿cómo dosis memory_profiler maneja los bucles, puede identificar el número de iteración del bucle?
Glen Fletcher
3
Identifica los bucles solo implícitamente cuando intenta informar la cantidad línea por línea y encuentra líneas duplicadas. En ese caso, solo tomará el máximo de todas las iteraciones.
Fabian Pedregosa
1
@FabianPedregosa ¿El memory_profilerbuffer almacena su salida? Puede que esté haciendo algo mal, pero parece que, en lugar de volcar el perfil para una función cuando se completa, espera a que finalice el script.
Greenstick
80

Recomiendo Dowser . Es muy fácil de configurar y no necesita cambios en su código. Puede ver recuentos de objetos de cada tipo a través del tiempo, ver la lista de objetos vivos, ver referencias a objetos vivos, todo desde la interfaz web simple.

# 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)

Importa memdebug y llama a memdebug.start. Eso es todo.

No he probado PySizer o Heapy. Agradecería las opiniones de los demás.

ACTUALIZAR

El código anterior es para CherryPy 2.X, CherryPy 3.Xel server.quickstartmétodo se ha eliminado y engine.startno toma la blockingbandera. Entonces, si estás usandoCherryPy 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()
sanxiyn
fuente
3
pero es solo para cherrypy, ¿cómo usarlo con un script simple?
Anurag Uniyal
13
No es para CherryPy. Piense en CherryPy como un kit de herramientas GUI.
sanxiyn
1
fwiw, la página pysizer pysizer.8325.org parece recomendar heapy, que se dice es similar
Jacob Gabrielson
66
Hay un puerto WSGI genérico de Dowser llamado Dozer, que también puede usar con otros servidores web: pypi.python.org/pypi/Dozer
Joe Shaw
2
cherrypy 3.1 eliminó cherrypy.server.quickstart (), así que solo use cherrypy.engine.start ()
MatsLindh
66

Considere la biblioteca objgraph (verhttp://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks para un caso de uso de ejemplo).

Charles Duffy
fuente
77
objgraph me ayudó a resolver un problema de pérdida de memoria que enfrentaba hoy. objgraph.show_growth () fue particularmente útil
Ngure Nyaga
1
Yo también encontré el objgraph realmente útil. Puede hacer cosas como objgraph.by_type('dict')entender de dónde dictprovienen todos esos objetos inesperados .
Dino
18

Muppy es (otro más) Memory Usage Profiler para Python. El enfoque de este conjunto de herramientas se basa en la identificación de pérdidas de memoria.

Muppy intenta ayudar a los desarrolladores a identificar fugas de memoria de las aplicaciones Python. Permite el seguimiento del uso de la memoria durante el tiempo de ejecución y la identificación de objetos con fugas. Además, se proporcionan herramientas que permiten localizar la fuente de objetos no liberados.

Serrano
fuente
13

Estoy desarrollando un generador de perfiles de memoria para Python llamado memprof:

http://jmdana.github.io/memprof/

Le permite registrar y trazar el uso de memoria de sus variables durante la ejecución de los métodos decorados. Solo tiene que importar la biblioteca usando:

from memprof import memprof

Y decora tu método usando:

@memprof

Este es un ejemplo de cómo se ven las tramas:

ingrese la descripción de la imagen aquí

El proyecto está alojado en GitHub:

https://github.com/jmdana/memprof

jmdana
fuente
3
¿Como lo uso? ¿Qué es a, b, c?
tommy.carstensen
@ tommy.carstensen a, by cson los nombres de las variables. Puede encontrar la documentación en github.com/jmdana/memprof . Si tiene alguna pregunta, no dude en enviar un problema en github o enviar un correo electrónico a la lista de correo que se puede encontrar en la documentación.
jmdana
12

Encontré que las melias son mucho más funcionales que Heapy o PySizer. Si está ejecutando una aplicación web wsgi, entonces Dozer es un buen contenedor de middleware de Dowser

Calen Pennington
fuente