2012-08-14 15 views
6

Tengo un script muy simple que asigna memoria, dels la única referencia a un objeto considerable, al mismo tiempo imprime heapy y pidstat informes. Después de ejecutar la secuencia de comandos, heapy me dice que no debe haber la cantidad de memoria que se utiliza mientras pidstat me dice lo contrario:python - la memoria no se devuelve al kernel

from guppy import hpy 
import time 
import sys 
import os 

''' 
1) print heapy and pidstat report after starting and before actually doing any work 
2) allocate some memory in a simple 2d array 
3) print heapy and pidstat report 
4) del the d2 array (attempt at garbage collection) 
5) print heapy and pidstat report 
6) sleep so pidstat can continue to be run to check on memory 
''' 

def pidstat(msg): 
    print '===============================' 
    print msg 
    os.system('pidstat -r -p %s' % os.getpid()) 
    print '+++++++++++++++++++++++++++++++' 
    print hpy().heap()[0] 
    print '===============================' 

pidstat('before doing anything') 
docs = [] 
for doc in range(0, 10000): 
    docs.append([j for j in range(0, 1000)]) 

pidstat('after fetching all the docs into memory') 
del docs 

pidstat('after freeing the docs') 
time.sleep(60) 

La salida se ve de la siguiente manera:

 
=============================== 
before doing anything 
Linux 2.6.38-15-generic (hersheezy)  08/14/2012 _x86_64_ (4 CPU) 

01:05:20 PM  PID minflt/s majflt/s  VSZ RSS %MEM Command 
01:05:20 PM  5360  0.44  0.00 44768 9180 0.11 python 
+++++++++++++++++++++++++++++++ 
Partition of a set of 19760 objects. Total size = 1591024 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
    0 19760 100 1591024 100 1591024 100 str 
=============================== 
=============================== 
after fetching all the docs into memory 
Linux 2.6.38-15-generic (hersheezy)  08/14/2012 _x86_64_ (4 CPU) 

01:05:21 PM  PID minflt/s majflt/s  VSZ RSS %MEM Command 
01:05:21 PM  5360  8.95  0.00 318656 279120 3.49 python 
+++++++++++++++++++++++++++++++ 
Partition of a set of 7431665 objects. Total size = 178359960 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
    0 7431665 100 178359960 100 178359960 100 int 
=============================== 
=============================== 
after freeing the docs 
Linux 2.6.38-15-generic (hersheezy)  08/14/2012 _x86_64_ (4 CPU) 

01:05:29 PM  PID minflt/s majflt/s  VSZ RSS %MEM Command 
01:05:29 PM  5360  40.23  0.00 499984 460480 5.77 python 
+++++++++++++++++++++++++++++++ 
Partition of a set of 19599 objects. Total size = 1582016 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
    0 19599 100 1582016 100 1582016 100 str 
=============================== 

¿Cómo puedo estar seguro de esto la memoria se devuelve al sistema operativo?

+1

posible duplicado de [¿Por qué la memoria no se libera al sistema después de grandes consultas (o series de consultas) en django?] (Http://stackoverflow.com/questions/5494178/why-doesnt-memory-get- released-to-system-after-large-queries-or-series-of-quer) –

Respuesta

3

Puede haber una diferencia entre cuando la memoria está disponible para su reutilización dentro del proceso python y cuando se lanza al sistema operativo. En particular, el intérprete estándar de Python (CPython) mantiene sus propios grupos y listas gratuitas para determinados tipos de objetos. Reutilizará la memoria en estas agrupaciones, pero nunca la liberará en el sistema operativo una vez que se haya utilizado.

Consulte this para obtener más información.

+1

Creo que responde la pregunta publicada. Mis verdaderas preguntas provienen de tener un daemon python de larga duración que asigna una tonelada de memoria (~ 60% de la memoria del sistema) una vez al día durante un período de tiempo muy corto. Después de terminar de ejecutar, el uso de la memoria se mantiene alto a pesar de que limpie mis referencias. ¿Algún consejo general? El enlace que publicaste parecía decir que simplemente no debería asignar tanta memoria en primer lugar ... – Hersheezy

+0

¿Alguna posibilidad de que puedas hacer algo que requiera mucha memoria en un segundo script, o algo por el estilo? ¿O lanzar una segunda instancia del daemon cuando comienza el procesamiento de memoria hambrienta, luego simplemente salir después del procesamiento (permitiendo que la segunda instancia continúe ejecutándose)? – kindall

+2

@Hersheezy: esta respuesta suena plausible pero es falsa. CPython * puede * liberar memoria algunas veces. Ver [mi comentario] (http://stackoverflow.com/questions/11957539/python-memory-not-being-given-back-to-kernel#comment15934886_11957625) – jfs

1

¿Cómo puedo asegurarme de que esta memoria vuelva al sistema operativo?

Generalmente no lo hará. Python asigna memoria en 'arenas', e incluso cuando las referencias se eliminan en el intérprete, se mantendrá en esa arena de memoria para usar más tarde. PIENSO que hay un mecanismo en la versión más nueva de python para anular arenas si están completamente vacías. Pero no tienes control sobre dónde se colocan tus objetos.

+2

[python podría lanzar arenas vacías] (http://bugs.python.org/issue1123430) en 2005. Aunque podría [dejar de funcionar] ] (http://bugs.python.org/msg134992) – jfs

Cuestiones relacionadas