Encuentra todas las referencias a un objeto en python

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

La razón por la que pregunto es que parece que tenemos una “pérdida de memoria”. Estamos cargando archivos de imágenes al servidor desde un navegador web. Cada vez que hacemos esto, el uso de memoria en el servidor aumenta proporcionalmente al tamaño del archivo que se acaba de cargar. La recolección de elementos no utilizados de python nunca libera esta memoria, por lo que creo que probablemente haya referencias extraviadas que indiquen que los datos de la imagen no se eliminan ni se salen del scope, incluso al final de cada solicitud.

Me imagino que sería bueno poder preguntarle a Python: “¿Qué referencias apuntan a esta memoria?” de modo que pueda averiguar qué es lo que impide que la recolección de basura la libere.

Actualmente estamos ejecutando Python y Django en un servidor Heroku.

Cualquier sugerencia e ideas son apreciadas, muchas gracias!

La biblioteca estándar de Python tiene un módulo gc que contiene la API del recolector de basura. Una de las funciones que posiblemente quieras tener es

 gc.get_objects() 

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

Si conoce el objeto que desea rastrear, puede usar la función getrefcount del módulo sys :

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

El módulo gc de Python tiene varias funciones útiles, pero suena como gc.get_referrers() es lo que estás buscando. Aquí hay 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 ejecuto eso, veo el siguiente resultado:

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

Puedes ver que la primera línea es l y d , y la segunda línea es solo l .

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