Erreurs de mémoire et limites de liste?

je dois produire de grandes et grandes (très) matrices (chaînes de Markov) à des fins scientifiques. J'effectue le calcul que j'ai mis dans une liste de 20301 éléments (=une rangée de ma matrice). J'ai besoin de toutes ces données en mémoire pour procéder à la prochaine étape de Markov, mais je peux les stocker ailleurs (par exemple Fichier) si nécessaire, même si elle ralentira mon Markov chaîne walk-through. Mon ordinateur (laboratoire scientifique): Bi-xenon 6 Core / 12threads chacun, mémoire de 12 Go, OS: win64

  Traceback (most recent call last):
  File "my_file.py", line 247, in <module>
    ListTemp.append(calculus)
MemoryError

exemple de calcul résultats: 9.233747520008198 e-102 (oui, c'est plus de 1/9000)

l'erreur est soulevée lors du stockage du 19766e élément:

ListTemp[19766]
1.4509421012263216e-103

si je vais plus loin

Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    ListTemp[19767]
IndexError: list index out of range

donc cette liste avait une erreur de mémoire à la boucle 19767.

Questions:

  1. y a-t-il une limite de mémoire à une liste? Est-il une "liste" de limite ou d'une "limite globale par script"?

  2. Comment contourner ces limites? Toutes les possibilités à l'esprit?

  3. sera-t-il utile d'utiliser numpy, python64? Quel les limites de mémoire sont-elles avec eux? Quel sur d'autres langues?

50
demandé sur martineau 2011-04-04 15:09:38

4 réponses

tout d'abord, voir quelle taille peut avoir un tableau Python? et Numpy, problème avec long de tableaux

Deuxième, la seule limite vient de la quantité de mémoire que vous avez et de votre système stocke les références de mémoire. Il n'y a pas de limite par liste, donc Python ira jusqu'à ce qu'il manque de mémoire. Deux possibilités:

  1. si vous utilisez un ancien système D'exploitation ou un système qui oblige les processus à utiliser une quantité limitée de mémoire, vous pouvez avoir besoin d'augmenter la quantité de mémoire à laquelle le processus Python a accès.
  2. briser la liste en utilisant chunking. Par exemple, faites les 1000 premiers éléments de la liste, sélectionnez et sauvegardez-les sur le disque, puis faites les 1000 suivants. Pour travailler avec eux, débranchez un morceau à la fois pour ne pas manquer de mémoire. Il s'agit essentiellement de la même technique que les bases de données utilisent pour travailler avec plus de données qu'il n'y en a en RAM.
43
répondu G Gordon Worley III 2017-05-23 11:54:27

l'exception MemoryError que vous voyez est le résultat direct de manquer de RAM disponible. Cela pourrait être dû soit à la limite de 2 Go par programme imposée par Windows ( 32bit programs ), soit au manque de RAM disponible sur votre ordinateur. (Ce" lien est à une question précédente).

vous devriez être en mesure d'étendre le 2Go en utilisant une copie 64bit de Python, à condition que vous utilisiez une copie 64bit de windows.

le IndexError serait causé parce que Python a frappé l'exception MemoryError avant de calculer le tableau entier. Encore une fois c'est un problème de mémoire.

pour contourner ce problème, vous pouvez essayer d'utiliser une copie 64bit de Python ou mieux encore trouver un moyen d'écrire vos résultats au fichier. À cette fin, regardez de numpy mapped arrays .

Vous devriez être en mesure de vous courir ensemble du calcul dans l'une de ces les tableaux que les données seront écrites disque, et seulement une petite partie de la mémoire.

20
répondu thomas 2017-05-23 12:25:54

il n'y a pas de limite de mémoire imposée par Python. Cependant, vous obtiendrez un MemoryError si vous n'avez plus de mémoire vive. vous dites que vous avez 20301 éléments dans le list . Cela semble trop petit pour causer une erreur de mémoire pour les types de données simples (par exemple int ), mais si chaque élément lui-même est un objet qui prend beaucoup de mémoire, vous pourriez bien être à court de mémoire.

le IndexError cependant est probablement causé parce que votre ListTemp a obtenu seulement 19767 éléments (indexé de 0 à 19766), et vous essayez d'accéder, après le dernier élément.

il est difficile de dire ce que vous pouvez faire pour éviter d'atteindre la limite sans savoir exactement ce que vous essayez de faire. Utiliser numpy pourrait aider. Il semble que vous stockez une énorme quantité de données. Il se peut que vous n'avez pas besoin de stocker tous à chaque étape. Mais il est impossible de dire sans le savoir.

5
répondu MAK 2011-04-04 11:20:40

Si vous voulez contourner ce problème, vous pouvez également utiliser l'étagère. Ensuite, vous créeriez des fichiers qui seraient de la taille de la capacité de vos machines à gérer, et ne les mettriez sur la RAM que si nécessaire, essentiellement en écrivant à la HD et en récupérant l'information en morceaux afin que vous puissiez la traiter.

Créer fichier binaire et vérifier si l'information est déjà dedans si oui faire une variable locale pour le tenir sinon écrire quelques données que vous jugez nécessaires.

Data = shelve.open('File01')
   for i in range(0,100):
     Matrix_Shelve = 'Matrix' + str(i)
     if Matrix_Shelve in Data:
        Matrix_local = Data[Matrix_Shelve]
     else:
        Data[Matrix_Selve] = 'somenthingforlater'

J'espère que ça n'a pas l'air trop archaïque.

0
répondu Eduardo Dias Florentino 2018-03-30 19:21:18