¿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.


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.


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

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

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


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.


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


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


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.