2010-10-14 8 views
11

Tengo un diccionario relativamente grande en Python y me gustaría poder no solo eliminar elementos de él, sino que realmente recuperar la memoria de estas eliminaciones en mi programa. Me encuentro corriendo a través de un problema por el cual, aunque elimino elementos del diccionario e incluso ejecuto el recolector de elementos no utilizados manualmente, parece que Python no está liberando la memoria.Recuperación de memoria de Python después de eliminar elementos en un diccionario

Un ejemplo sencillo de esto:

>>> tupdict = {} 
# consumes around 2 GB of memory 
>>> for i in xrange(12500000): 
... tupdict[i] = (i,i) 
... 
# delete over half the entries, no drop in consumed memory 
>>> for i in xrange(7500000): 
... del tupdict[i] 
... 
>>> import gc 
# manually garbage collect, still no drop in consumed memory after this 
>>> gc.collect() 
0 
>>> 

Me imagino lo que está sucediendo es que, aunque las entradas se eliminan y ejecución recolector de basura, Python no seguir adelante y cambiar el tamaño del diccionario. Mi pregunta es, ¿hay alguna manera simple de evitar esto, o es probable que necesite un replanteamiento más serio sobre cómo escribo mi programa?

+0

¿Cómo se mide el consumo de memoria? – stonemetal

+0

Nada sofisticado: monitor del sistema en Ubuntu –

+0

Ejecutar 'gc.collect()' en Python 2.6.5 en Windows XP SP3 parece liberar aproximadamente el 50% de la memoria –

Respuesta

18

Son muchos los factores que intervienen en si Python devuelve esta memoria al sistema operativo subyacente o no, que es probablemente la forma en que intentas saber si la memoria se está liberando. CPython tiene un sistema de asignación agrupada que tiende a conservar la memoria liberada para que pueda reutilizarse de manera eficiente (pero estas asignaciones posteriores no aumentarán la huella de su memoria desde la perspectiva del sistema operativo), que podría ser lo que usted ' viendo.

Además, en algunos procesos de plataforma unix, no libera la memoria liberada al sistema operativo hasta que se cierra la aplicación (o se produce algún otro evento significativo). Incluso si se encuentra en una situación en la que se ha liberado una agrupación completa (y Python podría decidir liberarla() en lugar de mantenerla abierta para objetos futuros), el SO todavía no liberará esta memoria para ser utilizada por otros procesos. (pero puede usarse para una reasignación adicional dentro del proceso original). En general, esto es bueno para reducir la fragmentación de la memoria y no tiene demasiadas desventajas, ya que la memoria del proceso no utilizado se localizará en el disco. Windows libera la memoria del proceso en el sistema operativo para su uso con cualquier nueva asignación (que luego puede ver en el Administrador de tareas), por lo que probar esto en Windows probablemente aparezca para darle un resultado diferente.

Al final, cómo administrar la memoria de proceso desasignada es el ámbito del sistema operativo, y hay varios esquemas (con ventajas y desventajas) utilizados de modo que simplemente mirando en su herramienta de información de sistema no necesariamente dirá tu toda la verdad

5

Tiene razón en que Python no cambia el tamaño del diccionario si los elementos se eliminan del diccionario. Esto no tiene nada que ver con la administración de memoria del sistema operativo y la recolección de basura, es un detalle de implementación de la estructura de datos dict de Python.

Una solución consiste en crear un nuevo diccionario copiando el diccionario anterior. Consulte este excelente video para obtener más información: http://pyvideo.org/video/276/the-mighty-dictionary-55 (alrededor de las 26:30 hay una respuesta).

Cuestiones relacionadas