web-dev-qa-db-fra.com

La définition de tableaux numpy sur Aucune mémoire disponible?

J'ai des centaines de matrices vraiment grandes, comme celles en forme (600, 800) ou (3, 600, 800).

Par conséquent, je veux désallouer la mémoire utilisée dès que je n'ai plus vraiment besoin de quelque chose.

J'ai pensé:

some_matrix = None

Doit faire le travail, ou est-ce que la référence est définie sur None mais quelque part dans la mémoire, l'espace est toujours alloué? (comme conserver l'espace alloué pour une nouvelle réinitialisation de some_matrix à l'avenir)

De plus: parfois je coupe les matrices, je calcule quelque chose et je mets les valeurs dans un tampon (une liste, car elle est ajoutée en permanence). Donc, définir une liste sur Aucun libérera définitivement la mémoire, non?

Ou existe-t-il une sorte de méthode unset() où des identifiants entiers plus ses objets référencés sont "supprimés"?

16
daniel451

Vous voulez certainement jeter un œil à la garbage collection . Contrairement à certains langages de programmation comme C/C++ où le programmeur doit libérer de la mémoire allouée dynamiquement par lui-même lorsque l'espace n'est plus nécessaire, python a un garbage collection. Cela signifie que python lui-même libère la mémoire lorsque necessary.

Lorsque vous utilisez some_matrix = None, vous dissociez la variable de l'espace mémoire; le compteur de référence est diminué et s'il atteint 0, le garbage collector va libérer la mémoire. Lorsque vous utilisez del some_matrix comme suggéré par MSeifert, la mémoire n'est pas libérée immédiatement contrairement à ce que dit la réponse. Selon doc python , c'est ce qui se passe:

La suppression d'un nom supprime la liaison de ce nom de l'espace de noms local ou global

Ce qui s'est passé sous le capot, c'est que le compteur de références à l'espace mémoire est réduit de 1 indépendamment de l'attribution de None ou de l'utilisation de del. Lorsque ce compteur atteint 0, le garbage collector free l'espace mémoire à l'avenir. La seule différence est que lorsque vous utilisez del, il est clair d'après le contexte que vous n'avez plus besoin du nom.

Si vous regardez le doc de la garbage collection, vous verrez que vous pouvez l'invoquer par vous-même ou modifier certains de ses paramètres.

18
innoSPG

Numpy supprime les tableaux lorsque le compteur de référence est égal à zéro (ou au moins il garde la trace du compteur de référence et laisse le système d'exploitation collecter les ordures).

Par exemple, avoir

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

va libérer la mémoire "immédiatement" (la manière préférée est d'écrire del a cependant)

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

ne libérera rien.


Vous avez également mentionné le tranchage. Le découpage n'est qu'une vue sur les données et donc exactement comme le deuxième exemple. Si vous ne supprimez pas les deux variables faisant référence au même tableau, le système d'exploitation conservera les tableaux.

Si je fais quelque chose de très cher en mémoire, je resterai toujours avec des fonctions séparées qui font l'opération et ne renvoient que ce qui est vraiment nécessaire. Les fonctions se nettoient après elles-mêmes afin que tous les résultats intermédiaires soient libérés (s'ils ne sont pas retournés).

7
MSeifert

Dans le cas où vous devriez faire quelque chose comme ci-dessous, la mémoire ne sera pas libérée bien qu'une copie de a sera faite implicitement:

a = np.ones((10000, 10000))
b = np.empty((10000, 10000))
b[:] = a
a = None
del a

Au lieu de cela, vous pouvez effectuer les opérations suivantes et la mémoire sera libérée après avoir fait a = None:

a = np.ones((10000, 10000))
b = np.empty((10000, 10000))
b[:] = np.copy(a)
a = None
del a
0
Amir