Python reclama memoria después de eliminar elementos en un diccionario

Tengo un diccionario relativamente grande en Python y me gustaría poder no solo eliminar elementos de él, sino recuperar la memoria de estas eliminaciones en mi progtwig. Me estoy topando con un problema por el cual, aunque elimino elementos del diccionario e incluso ejecuto el recolector de basura manualmente, Python no parece estar liberando la memoria en sí.

Un ejemplo simple 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 que lo que está sucediendo es que, aunque las entradas se eliminan y el recolector de basura se ejecuta, Python no avanza y cambia 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 progtwig?

Hay muchos factores que influyen en si Python devuelve o no esta memoria al sistema operativo subyacente, que es probablemente la forma en que se está intentando saber si se está liberando la memoria. CPython tiene un sistema de asignación agrupada que tiende a retener la memoria liberada para que pueda reutilizarse de una manera eficiente (pero estas asignaciones posteriores no boostán su huella de memoria desde la perspectiva del sistema operativo), lo que podría ser lo que usted cree. re viendo

Además, en algunas plataformas Unix, los procesos no liberan la memoria liberada al sistema operativo hasta que la aplicación se cierra (o se produce algún otro evento significativo). Incluso si se encuentra en una situación en la que se ha liberado un grupo completo (y, por lo tanto, Python podría decidir liberarlo () en lugar de mantenerlo abierto para objetos futuros), el sistema operativo aún no liberará esta memoria para que otros procesos la utilicen. (pero se puede utilizar para una mayor reasignación dentro del proceso original). En general, esto es bueno para reducir la fragmentación de la memoria y no tiene demasiados inconvenientes, ya que la memoria de proceso no utilizada se eliminará en el disco. Windows libera la memoria del proceso al sistema operativo para que la use cualquier nueva asignación (que luego puede ver en el Administrador de tareas), por lo que es probable que al intentarlo en Windows le dé un resultado diferente.

Al final, la forma de administrar la memoria de proceso desasignada es el ámbito del sistema operativo, y hay varios esquemas (con ventajas y desventajas) que se utilizan de tal manera que el solo hecho de buscar en la herramienta de elección de información del sistema no necesariamente le dirá toda la verdad. .

Tienes razón en que Python no cambia el tamaño del diccionario si se eliminan elementos del diccionario. Esto no tiene nada que ver con la gestión de la 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 es crear un nuevo diccionario copiando el diccionario antiguo. Consulte este gran video para obtener más información: http://pyvideo.org/video/276/the-mighty-dictionary-55 (alrededor de las 26:30 hay una respuesta).