2012-08-09 17 views
15

¿Cuál es una buena forma de encontrar todas las referencias a un objeto en python?Buscar todas las referencias a un objeto en python

La razón por la que pregunto es porque parece que tenemos una "fuga de memoria". Estamos cargando archivos de imagen al servidor desde un navegador web. Cada vez que hacemos esto, el uso de memoria que sube en el servidor aumenta proporcionalmente al tamaño del archivo que se acaba de cargar. Esta memoria nunca será liberada por la colección de basura de python, así que estoy pensando que probablemente haya referencias extraviadas que apunten a los datos de imagen que no se borran ni se salen del alcance, incluso al final de cada solicitud.

Creo que sería bueno poder preguntar a python: "¿Qué referencias siguen apuntando a este recuerdo?" para poder descifrar qué impide que la recolección de basura lo libere.

Actualmente estamos ejecutando Python y Django en un servidor Heroku.

¡Se agradecen todas las sugerencias e ideas, muchas gracias!

+0

http://stackoverflow.com/questions/1339293/python-memory-leak-debugging –

+0

¿Has mirado en esto: http://stackoverflow.com/questions/110259/python-memory-profiler –

Respuesta

10

La biblioteca estándar de Python tiene gc módulo que contiene el recolector de basura API. Una de las funciones que es posible que desee tener es

gc.get_objects() 

Esta función lista de todos los objetos actualmente rastreados por recolector de basura regresa. El siguiente paso es analizarlo.

Si conoce el objeto que desee rastrear puede utilizar la función sys del módulo getrefcount: Módulo

>>> x = object() 
>>> sys.getrefcount(x) 
2 
>>> y = x 
>>> sys.getrefcount(x) 
3 
+9

sys.getrefcount() es útil, pero ¿hay alguna forma de ver cuáles son esas referencias? – RAAC

12

de Python gc tiene varias funciones útiles, pero suena como gc.get_referrers() es lo que estás buscando. He aquí un ejemplo:

import gc 


def foo(): 
    a = [2, 4, 6] 
    b = [1, 4, 7] 

    l = [a, b] 
    d = dict(a=a) 
    return l, d 

l, d = foo() 
r1 = gc.get_referrers(l[0]) 
r2 = gc.get_referrers(l[1]) 

print r1 
print r2 

Cuando corro, veo el siguiente resultado:

[[[2, 4, 6], [1, 4, 7]], {'a': [2, 4, 6]}] 
[[[2, 4, 6], [1, 4, 7]]] 

Se puede ver que la primera línea es l y d, y la segunda línea es sólo l.

En mis breves experimentos, he encontrado que los resultados no siempre son tan claros. Las cadenas y tuplas internas, por ejemplo, tienen más referentes de lo que cabría esperar.

+1

Esta parece ser la respuesta más simple y mejor. –

Cuestiones relacionadas