font python optimization memory-management garbage-collection

font - Colección de basura Python



subplot title python (7)

Aquí hay una cosa que puede hacer en el REPL para forzar una desreferenciación de una variable:

>>> x = 5 >>> x 5 >>> del x >>> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name ''x'' is not defined

He creado un código python que crea un objeto en un bucle, y en cada iteración sobrescribe este objeto con uno nuevo del mismo tipo. Esto se hace 10.000 veces, y Python toma 7mb de memoria por segundo hasta que se use mi RAM de 3gb. ¿Alguien sabe de una forma de eliminar los objetos de la memoria?


Creo que esta es una referencia circular (aunque la pregunta no es explícita sobre esta información).

Una forma de resolver este problema es invocar manualmente la recolección de basura. Cuando ejecuta manualmente el recolector de basura, también barrerá los objetos de referencia circular.

import gc for i in xrange(10000): j = myObj() processObj(j) #assuming count reference is not zero but still #object won''t remain usable after the iteration if !(i%100): gc.collect()

Aquí no ejecute el recolector de basura con demasiada frecuencia porque tiene su propia sobrecarga, por ejemplo, si ejecuta el recolector de basura en cada ciclo, la interpretación será extremadamente lenta.


Encontré que en mi caso (con Python 2.5.1), con referencias circulares que involucran clases que tienen __del__() , no solo no estaba ocurriendo la recolección de basura de manera oportuna, nunca se llamaron los métodos __del__() de mis objetos , incluso cuando el script salió. Así que utilicé weakref para romper las referencias circulares y todo estaba bien.

Felicitaciones a Miles que proporcionó toda la información en sus comentarios para mí para armar esto.


Este es un error antiguo que se corrigió para algunos tipos en Python 2.5. Lo que sucedía era que Python no era tan bueno coleccionando cosas como listas vacías / diccionarios / tupes / floats / ints. En Python 2.5, esto se solucionó ... principalmente. Sin embargo, los flotantes y los ints son singleton para las comparaciones, por lo que una vez que se crea uno, permanece mientras el intérprete esté vivo. Me han picado mucho peor cuando se trata de una gran cantidad de carrozas, ya que tienen la horrible costumbre de ser únicos. Esto se caracterizó por python 2.4 y se actualizó al doblarlo en python 2.5

La mejor manera que he encontrado a su alrededor es actualizar a Python 2.5 o posterior para ocuparse del problema de listas / diccionarios / tuplas. Para los números, la única solución es no permitir que grandes cantidades de números entren en python. Lo he hecho con mi propio contenedor a un objeto de C ++, pero tengo la impresión de que numpy.array dará resultados similares.

Como script de publicación, no tengo idea de qué pasó con esto en Python 3, pero sospecho que los números aún forman parte de un singleton. Entonces, la fuga de memoria es en realidad una característica del lenguaje.


No ha proporcionado suficiente información; esto depende de los detalles del objeto que está creando y de lo que está haciendo con él en el ciclo. Si el objeto no crea referencias circulares, debe desasignarse en la siguiente iteración. Por ejemplo, el código

for x in range(100000): obj = " " * 10000000

no dará como resultado una asignación de memoria cada vez mayor.


Si está creando referencias circulares, sus objetos no serán desasignados inmediatamente, sino que tendrán que esperar a que se ejecute un ciclo de GC.

Puede usar el módulo weakref para resolver este problema o weakref explícitamente sus objetos después de su uso.


weakref se puede usar para código estructurado de objeto circular como en el ejemplo explicado