2013-04-29 7 views
10

Ho 50 file pickle da 0,5 GB ciascuno. Ogni file pickle è composto da un elenco di oggetti classe personalizzati. Non ho problemi di caricare i file singolarmente utilizzando la funzione seguente:Come evitare perdite di memoria quando carico file di pickle di grandi dimensioni in un ciclo for?

def loadPickle(fp): 
    with open(fp, 'rb') as fh: 
     listOfObj = pickle.load(fh) 
    return listOfObj 

Tuttavia, quando provo a caricare i file in modo iterativo ottengo una perdita di memoria.

l = ['filepath1', 'filepath2', 'filepath3', 'filepath4'] 
for fp in l: 
    x = loadPickle(fp) 
    print('loaded {0}'.format(fp)) 

La memoria viene espulsa prima dello loaded filepath2. Come posso scrivere codice che garantisca che sia caricato un solo pickle durante ogni iterazione?

Le risposte a domande correlate su SO suggeriscono l'utilizzo di oggetti definiti nel modulo weakref o la garbage collection esplicita utilizzando il modulo gc, ma sto avendo difficoltà a capire come applicare questi metodi al mio caso d'uso specifico. Questo perché ho una comprensione insufficiente di come funziona la referenziazione sotto il cofano.

correlati: Python garbage collection

+0

prova ad aggiungere 'x = Nessuno' subito dopo' per fp in l: ' –

+0

Ciao Ionut Hulub, grazie. Ha funzionato! –

+2

Qui non c'è alcuna perdita di memoria. È solo che il vecchio valore 'x' non può essere rilasciato fino a quando non viene assegnato il nuovo valore, quindi è necessario disporre di memoria sufficiente per avere due valori in memoria contemporaneamente. – abarnert

risposta

7

È possibile risolvere che con l'aggiunta x = None subito dopo for fp in l:.

Il motivo per cui questo funziona è perché verrà annullata la variabile x, in attesa che il garbage collector python liberasse memoria virtuale prima di chiamare loadPickle() la seconda volta.

+1

In questo modo non è garantito il funzionamento. Python è _allowed_ per eliminare l'oggetto quando si interrompe il riferimento a esso, ma non è _questito a. Fortunatamente, l'implementazione CPython farà tutto questo, a patto che non si abbiano riferimenti circolari da nessuna parte, ma il codice che dipende da qualcosa che è esplicitamente documentato per non essere garantito dovrebbe per lo meno venire con commenti e avvertimenti ... – abarnert

+0

Questo è vero . Grazie per l'aggiunta @abarnert –

+7

Non sarebbe meglio fare 'del x'? Giusto per essere sicuro che la variabile 'x' sarà dereferenziata. – juliomalegria

Problemi correlati