2013-04-28 9 views
34

AGGIORNAMENTO: - Questo problema si risolveva da solo dopo il riavvio della macchina. Non ancora in grado di capire perché questo errore stava accadendo prima.Rilascio memoria di un enorme array numpy in IPython

Ho una funzione che carica un enorme array numpy (~ 980 MB) e lo restituisce.

Quando avvio Ipython per la prima volta e chiamo questa funzione, carica la matrice nella variabile senza alcun problema.

Ma se eseguo di nuovo lo stesso comando, esce sollevando un "Errore di memoria".

Ho provato quanto segue,

del hugeArray 

ancora lo stesso errore si ebbero. Ho anche provato il seguente

del hugeArray 
gc.collect() 
gc.collect() 

Inizialmente, gc.collect() restituito 145 e la seconda chiamata restituito 48. Ma anche dopo questo quando chiamo la funzione, era ancora sollevando un errore di memoria.

L'unico modo per caricare nuovamente era il riavvio di ipython. C'è qualcosa che posso fare per liberare tutta la memoria in ipython, così che non devo riavviarlo?

---------------- Aggiornamento

seguito è l'output di %whos

Variable Type  Data/Info 
------------------------------ 
gc   module <module 'gc' (built-in)> 
gr   module <module 'Generate4mRamp' <...>rom 'Generate4mRamp.pyc'> 
np   module <module 'numpy' from '/us<...>ages/numpy/__init__.pyc'> 
plt  module <module 'matplotlib.pyplo<...>s/matplotlib/pyplot.pyc'> 

Di questi, gr è il mio modulo che contiene la funzione che ho usato per caricare il cubo di dati.

--------- Come riprodurre l'errore

Il seguente semplice funzione è in grado di riprodurre l'errore.

import numpy as np 
import gc 

def functionH(): 
    cube=np.zeros((200,1024,1024)) 
    return cube 

testcube=functionH() #Runs without any issue 

del testcube 
testcube=functionH() # Raises Memory Error 

del testcube 
gc.collect() 
gc.collect() 
testcube=functionH() # Still Raises Memory Error 

Questo errore si verifica solo in ipython. In semplice python (>>>) dopo aver dato del testcube, non vi è alcun errore di memoria.

+1

Puoi provare a chiamare 'whos' in ipython per scoprire cosa sta occupando la memoria? – tiago

+0

@tiago: ho aggiunto l'output del comando% whos. Non mostra nient'altro che i moduli che ho caricato. – indiajoe

+0

Puoi mostrare il numero di riferimento dell'oggetto prima di cancellarlo? 'import sys; sys.getrefcount (testcube)' – HYRY

risposta

43

Stai guardando il valore? IPython memorizza nella cache le variabili di output come ad es. Out[8], quindi se lo si esamina, verrà tenuto in memoria.

È possibile eseguire %xdel testcube per eliminare la variabile e rimuoverla dalla cache di IPython. In alternativa, %reset out o %reset array cancellerà tutta la cronologia di output o solo i riferimenti agli array numpy.

+0

Non stavo guardando il valore in IPython. Ma grazie per queste informazioni su Ipython che memorizza nella cache le uscite. Non lo sapevo. Proverò questo comando xdel anche quando questo errore si verifica la prossima volta. In questo momento, tutto funziona perfettamente. – indiajoe

+2

C'è un motivo per non funzionare correttamente? Provo a fare qualcosa come 'list ([i ** 2 per i in range (30000000)])' per testare questo, e poi provo a fare il reset%. Out è vuoto dopo, ma la memoria è ancora occupata come prima del comando reset, perché potrebbe essere? È come se rimuovesse solo il riferimento. ma non rilasciando memoria? – Marko

+0

Dovrei aggiungere che% reset, senza 'out' funziona. Entrambi svuota la memoria e rimuove i riferimenti. Ma non voglio perdere le mie variabili. Inoltre, questo funziona 'v = Out [18]% xdel v'. Perché? – Marko