2012-09-14 17 views
17

en muchos casos, está seguro de que definitivamente no va a utilizar la lista de nuevo, espero que la memoria se debe liberar en este momentocómo liberar memoria usada inmediatamente en la lista de Python?

a = [11,22,34,567,9999] 
del a 

no estoy seguro de si realmente libera la memoria, puede utilizar

del a[:] 

que en realidad eliminan todos los elementos de la lista a.

por lo que la mejor manera de liberar es esto?

def realse_list(a): 
    del a[:] 
    del a 

no estoy seguro.necesita tu opinión.

por cierto, ¿qué hay de la tupla y el conjunto?

+9

a menos que tenga que lidiar con una gran cantidad de datos y en realidad está recibiendo una excepción MemoryError, no se preocupe por la administración de la memoria. – monkut

Respuesta

19
def release_list(a): 
    del a[:] 
    del a 

No nunca hacer esto. Python libera automáticamente todos los objetos a los que ya no se hace referencia, por lo que un simple del a asegura que la memoria de la lista se liberará si la lista no se referencia en ningún otro lado. Si ese es el caso, los elementos de la lista individual también se liberarán (y cualquier objeto al que se haga referencia solo a ellos, y así sucesivamente), a menos que algunos de los elementos individuales también sigan siendo referenciados.

Eso significa el tiempo solamente cuandodel a[:]; del a dará a conocer más de del a por sí solo es cuando se hace referencia a otro lugar de la lista. Esto es precisamente cuando no debería vaciar la lista: ¡alguien más todavía lo está usando!

Básicamente, no debería pensar en administrar piezas de memoria. En cambio, piense en administrar referencias a objetos.En el 99% de todos los códigos Python, Python limpia todo lo que no necesita muy pronto después de la última vez que lo necesitó, y no hay problema. Cada vez que una función finaliza todas las variables locales en esa función "mueren", y si apuntaban a objetos que no están referenciados en ningún otro lugar, se eliminarán y eso se aplicará en cascada a todo lo que se encuentre dentro de esos objetos.

La única vez que necesita pensar en ello es cuando tiene un objeto grande (digamos una gran lista), hace algo con él, y luego comienza un subcomputación de larga duración (o que requiere mucha memoria), donde el objeto grande no es necesario para el sub-cálculo. Debido a que tiene una referencia, el objeto grande no se liberará hasta que finalice el cálculo secundario y luego regrese. En ese tipo de caso (y solo ese tipo de caso), puede explícitamente del su referencia al objeto grande antes de comenzar el subcomputado, de modo que el objeto grande pueda liberarse antes (si nadie más está utilizándolo, si una persona que llama le pasó el objeto y la persona que llama lo hace y aún lo necesita después de su regreso, será muy contento de que no se publique).

+0

¿Qué tal si ** a ** es una variable miembro (una grande) y sé que ya no la usaré más, esto cuenta como una "variable referenciada"? El escenario es simple: tengo un objeto que procesa una gran lista _when_needed_. Después de llamar a algún método, se procesa la lista ** a ** y guardo los resultados en caché. En este caso, sé que ya nunca necesitaré ** a **. – hsgubert

+1

@hsgubert Si 'a' es un atributo de algún objeto (variable de miembro), entonces sí se hace referencia al ser parte de ese objeto (suponiendo que el objeto se haga referencia en alguna parte). Pero si sabes que ya no lo necesitas y estás en un método de la misma clase, puedes 'del self.a' deshacerte de él. Si no estás en un método de esa clase, no te metas con eso. Un buen diseño casi siempre mantiene a cada clase responsable de administrar sus propios atributos; es muy difícil entender una clase si * otras * partes del programa pueden decidir al azar que el objeto ya no necesita uno de sus atributos. – Ben

4

Como notas de @monkut, probablemente no deberías preocuparte demasiado por la administración de la memoria en la mayoría de las situaciones. Si usted tiene una lista gigante que está seguro de que haya terminado con ahora y no va a salir del ámbito de la función actual por un tiempo, sin embargo:

del a simplemente elimina su nombre para que a pedazo de memoria. Si alguna otra función o estructura o lo que sea tiene una referencia todavía, no será eliminada; si este código tiene la única referencia a esa lista con el nombre a y está usando CPython, el contador de referencia lo liberará inmediatamente. Es posible que otras implementaciones (PyPy, Jython, IronPython) no lo eliminen de inmediato porque tienen diferentes recolectores de basura.

Debido a esto, la instrucción del a en su función realse_list en realidad no hace nada, ¡porque la persona que llama todavía tiene una referencia!

del a[:] será, como se señala, eliminar los elementos de la lista y, por tanto, probablemente la mayor parte de su uso de memoria.

Puede hacer the_set.clear() para un comportamiento similar con los conjuntos.

Todo lo que puedes hacer con una tupla, porque son inmutables, es del the_tuple y espero que nadie más tenga una referencia, ¡pero es probable que no tengas enormes tuplas!

+1

Esta respuesta sería sustancialmente más completa con una discusión de referencias débiles. – Marcin

1

Si le preocupa la gestión de la memoria y el rendimiento de los tipos de datos, por qué no utilizar algo así como una doble cola vinculada.

En primer lugar, su espacio de memoria está disperso a través de la memoria por lo que no tendrá que asignar una gran cantidad de memoria continua desde el principio. En segundo lugar verás tiempos de acceso más rápidos para enqueueing y dequeueing porque a diferencia de una lista estándar cuando elimines digamos un elemento intermedio no hay necesidad de deslizar el resto de la lista en el índice que lleva tiempo en listas grandes .

También debería tener en cuenta que si usa solo números enteros, le sugiero que busque en un montón binario ya que verá O (log^2n) tiempos de acceso en comparación con O (N) con listas.

2

Python usa Reference Count para administrar su recurso.

import sys 
class foo: 
    pass 

b = foo() 
a = [b, 1] 

sys.getrefcount(b) # gives 3 
sys.getrefcount(a) # gives 2 

a = None # delete the list 
sys.getrefcount(b) # gives 2 

En el ejemplo anterior, el contador de referencia B se incrementará cuando se pone en una lista, y como se puede ver, cuando se elimina de la lista, el contador de referencias de B GET decrementa también. Por lo tanto, en su código

def release_list(a): 
    del a[:] 
    del a 

era redundante.

En resumen, todo lo que necesita hacer es asignar la lista a un objeto Ninguno o usar del palabra clave para eliminar la lista del diccionario de atributos. (a.k.a, para desvincular el nombre del objeto real). Por ejemplo,

a = None # or 
del a 

Cuando el recuento de referencias de un objeto se reduce a cero, python liberará la memoria por usted. Para asegurarse de que el objeto se elimine, debe asegurarse de que ningún otro lugar haga referencia al objeto por su nombre o contenedor.

sys.getrefcount(b) # gives 2 

Si sys.getrefcount le da 2, que significa que usted es el único que tenía la referencia del objeto y cuando lo hace

b = None 

se conseguirá liberarse de la memoria.

Cuestiones relacionadas