2010-11-14 15 views
11

Estoy haciendo algunos cálculos pesados ​​con Python (usando OpenCV y Numpy) y al final, termino con una gran cantidad de uso de memoria (> 1GB) por lo que todas las referencias deberían desaparecer y solo tengo el resultado final (que no debería ser más de unos pocos MB).Python: estadísticas de uso de memoria por tipos de objeto (o línea de código fuente)

Para depurar esto, sería bueno si pudiera obtener algunas estadísticas de alguna manera que me mostraran cuántas instancias de objetos hay de qué tipo, ordenados por la cantidad total de memoria que toman (por clase de objeto).

O incluso más: no por clase de objeto sino por línea de código fuente donde se creó el objeto (supongo que esta información no está disponible a menos que active alguna depuración en Python que haga que el cálculo sea demasiado lento, entonces no estoy seguro si eso sería útil).

¿Puedo obtener algunas estadísticas como esta de alguna manera? ¿O cómo voy a depurar esto?


Algunos me ha Missunderstood: Sólonecesito saber cómo depurar el uso de memoria. El procesamiento/tiempo de ejecución es perfecto.

+0

Para empezar, consulte http://docs.python.org/library/profile.html –

+0

Esto no responde a su pregunta, pero mira \ _ \ _ ranuras \ _ \ _ para reducir mucho el consumo de memoria. –

+0

@Rafe: Esto solo parece ser sobre el tiempo de ejecución, pero no sobre el uso de la memoria, ¿no? – Albert

Respuesta

8

Creo que estás buscando un generador de perfiles de Python;

usted tiene un montón de ellos que se puede utilizar, como Heapy, profile or cprofile, Pysize ...

ejemplo usando Heapy:

tiene que incluir este fragmento en algún lugar de su código:

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

y se le dará como salida:

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) 

ejemplo, con cprofile:

se puede ejecutar la siguiente manera:

python -m cProfile script.py 

Salida:

  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} 

También puede utilizar gc módulo para saber por qué Python es no liberador su memoria y para pedirle que libere la memoria usando gc.collect().

Por cierto, ha mirado numpy, creo que es más adecuado si está haciendo cálculos pesados ​​como usted dijo.

+2

No veo muy bien cómo puedo obtener estadísticas de memoria de cProfile. ¿Puedes explicar? – Albert

+0

Heapy parece ser más útil a partir de lo que muestra. Sin embargo, no parece dar salida correcta. Dice que el tamaño total es de aproximadamente 8 MB. Pero el proceso lleva aproximadamente> 1GB. – Albert

+0

Estaba usando las herramientas en objgraph (descrito [aquí] (http://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks)) y me da un resultado similar. Pero me pregunto por qué no muestra ninguna referencia 'str'. Sin embargo, ninguno de ellos muestra dónde está la mayor parte de la memoria (en la salida falta aproximadamente el 99% de la memoria real). Tal vez es una pérdida de memoria en una de las bibliotecas externas como OpenCV o Numpy? – Albert

6

Ok, lo busqué. Como ninguno de los perfiles de los archivos de Python proporciona ningún resultado útil (porque no pudieron encontrar la memoria), estaba bastante seguro de que algunas de las libretas externas (OpenCV) eran la fuente de la pérdida de memoria.

Y podría reproducir la pérdida mem con este simple código:

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

Algunos de los otros recursos para la depuración de Python mem que eran bastante interesante (no ayudaron en ese caso, pero puede haber útil para otros):

Cuestiones relacionadas