2016-02-10 14 views
7

Ho centinaia di matrici veramente grandi, tipo (600, 800) o (3, 600, 800) di forma.Imposta l'array numpy su Nessuna memoria libera?

Pertanto, desidero deselezionare la memoria utilizzata non appena non ho più bisogno di qualcosa.

ho pensato:

some_matrix = None 

dovrebbe fare il lavoro, o è solo il riferimento impostato su Nessuno, ma da qualche parte in memoria lo spazio ancora assegnato? (come preservare lo spazio allocato per una nuova inizializzazione di some_matrix in futuro)

Inoltre: a volte sto tagliando le matrici, calcolato qualcosa e collocato i valori in un buffer (una lista, perché viene aggiunta a tutti tempo). Quindi, impostare una lista su Nessuno sicuramente libererà la memoria, giusto?

Oppure esiste un qualche tipo di metodo unset() in cui gli identificatori completi più i relativi oggetti di riferimento sono "cancellati"?

risposta

8

Desiderate sicuramente dare un'occhiata allo garbage collection. A differenza di alcuni linguaggi di programmazione come C/C++ in cui il programmatore deve liberare la memoria allocata dinamicamente da solo quando lo spazio non è più necessario, python ha una garbage collection. Significa che Python stesso libera la memoria quando necessary.

Quando si utilizza some_matrix = None, si scollega la variabile dallo spazio di memoria; il contatore di riferimento viene diminuito e se raggiunge 0, il garbage collector libererà la memoria. Quando si utilizza del some_matrix come suggerito da MSeifert, la memoria non viene liberata immediatamente rispetto a ciò che dice la risposta.Secondo python doc, questo è ciò che accade:

cancellazione di un nome elimina il legame di questo nome dallo spazio dei nomi locale o globale

Che cosa è successo sotto il cofano è che il contatore di riferimenti al lo spazio di memoria viene ridotto di 1 indipendentemente dall'assegnazione di None o dall'utilizzo di del. Quando questo contatore raggiunge 0, il garbage collector avrà lo spazio di memoria free in futuro. L'unica differenza è che quando si utilizza del, è chiaro dal contesto che non è più necessario il nome.

Se si guarda il documento della garbage collection, si vedrà che è possibile richiamarlo da solo o modificare alcuni dei suoi parametri.

3

Numpy elimina gli array quando il contatore di riferimento è zero (o almeno tiene traccia del contatore di riferimento e consente al sistema operativo di raccogliere la spazzatura).

Ad esempio avente

import numpy as np 
a = np.linspace(0,100, 10000000) 
a = None 

libererà la memoria "immediatamente" (modo preferito sta scrivendo del a però) mentre

import numpy as np 
a = np.linspace(0,100, 10000000) 
b = a 
a = None 

libererà nulla.


Hai menzionato anche l'affettatura. Il taglio è solo una vista sui dati e quindi esattamente come il secondo esempio. Se non elimini entrambe le variabili che fanno riferimento allo stesso array, il sistema operativo manterrà gli array.

Se faccio qualcosa di molto costoso, rimarrò sempre con funzioni separate che eseguono l'operazione e restituiscono solo ciò che è veramente necessario. Le funzioni ripuliscono se stesse in modo da liberare i risultati intermedi (se non vengono restituiti).

+0

Grazie per il chiarimento di funzioni/metodi. Ho già dato per scontato che le variabili locali vengano gettate via dopo l'istruzione return (come in Java o in altri linguaggi) ma è bello sapere che Python fa esattamente la stessa identica cosa lì. Tuttavia, 'del some_array' o generalmente' del some_variable' dovrebbe sempre essere la prima scelta per liberare esplicitamente memoria ?! – daniel451

+0

'' del'' cancella il nome della variabile, quindi qualsiasi operazione successiva inclusa la variabile cancellata genererà un errore. '' a = None'' d'altra parte mantiene la variabile '' a'' così "potreste" accidentalmente usarlo successivamente e non rendersi conto che in realtà è "cancellato". – MSeifert

+0

Ok, grazie. Tuttavia, il secondo scenario non libererà nulla con 'del', anche tu ?! Quindi, 'del' sta eliminando l'identificatore più il suo riferimento, ma l'oggetto dietro il riferimento è appena cancellato quando nessun altro identificatore lo sta riferendo più, giusto? Quindi, finché qualsiasi altro identificatore fa riferimento all'oggetto, come 'b' nell'esempio, il garbage collector non cancellerà l'oggetto ?! – daniel451

Problemi correlati