MemoryError avec Cornichon en Python
Je suis de traitement de certaines données et je stocke les résultats dans les trois dictionnaires, et je l'ai enregistré sur le disque avec la saumure. Chaque dictionnaire a 500-1 000 MO.
Maintenant, je suis de chargement:
import pickle
with open('dict1.txt', "rb") as myFile:
dict1 = pickle.load(myFile)
Cependant, déjà, lors du chargement, le premier dictionnaire-je obtenir:
*** set a breakpoint in malloc_error_break to debug
python(3716,0xa08ed1d4) malloc: *** mach_vm_map(size=1048576) failed (error code=3)
*** error: can't allocate region securely
*** set a breakpoint in malloc_error_break to debug
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load
dispatch[key](self)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1019, in load_empty_dictionary
self.stack.append({})
MemoryError
Comment résoudre ce problème? Mon ordinateur a 16 go de RAM donc je trouve ça étrange que le chargement d'un 800 MO dictionnaire se bloque. Ce que je trouve surprenant, c'est qu'il n'y avait pas de problèmes lors de l'enregistrement des dictionnaires.
De plus, à l'avenir, je prévois de traiter plus de données résultant dans les grands dictionnaires (3-4 GO sur le disque), donc, tous les conseils pour améliorer l'efficience est apprécié.
Cela dépend de votre système d'exploitation, la quantité de mémoire qu'un processus est autorisé à allouer.
La taille est la taille du fichier sur le disque. Je suis sous Mac OS 10.10. Est-il un moyen de régler la quantité de mémoire est autorisé à allouer?
800 MO de données ne se traduit pas 800 MO de l'utilisation de la mémoire; il pourrait être plus grande ou peut-être petites, mais généralement plus grande. Comment avez-vous produire ces cornichons en premier lieu?
Et comment était votre
dict1
alors? Vous devez utiliser le sys.getsizeof()
de manière récursive pour obtenir l'empreinte mémoire de l'objet. Cette empreinte est tributaire de l'OS, et si vous utilisez une version 32 bits ou 64 bits processus.OriginalL'auteur flotr | 2015-01-21
Vous devez vous connecter pour publier un commentaire.
Si vos données dans les dictionnaires sont
numpy
tableaux, il y a des paquets (commejoblib
etklepto
) qui font le décapage de grandes baies efficace, à la fois comme leklepto
etjoblib
comprendre comment utiliser un minimum de représentation de l'état pour unnumpy.array
. Si vous n'avez pasarray
de données, ma suggestion serait d'utiliserklepto
pour stocker les entrées d'un dictionnaire en plusieurs fichiers (au lieu d'un seul fichier) ou à une base de données.Voir ma réponse à un très étroitement liés à la question https://stackoverflow.com/a/25244747/2379433, si vous êtes ok avec le décapage de plusieurs fichiers à la place d'un fichier unique, souhaitez enregistrer/charger vos données en parallèle, ou de l'expérience facilement avec un format de stockage et de backend pour voir ce qui fonctionne le mieux pour votre cas. Voir aussi: https://stackoverflow.com/a/21948720/2379433 pour d'autres améliorations possibles, et ici aussi: https://stackoverflow.com/a/24471659/2379433.
Comme les liens ci-dessus en discuter, vous pouvez utiliser
klepto
-- qui vous offre la possibilité de stocker facilement des dictionnaires de disque ou de base de données, à l'aide d'une API commune.klepto
vous permet également de choisir un format de stockage (pickle
,json
, etc.) --aussiHDF5
(ou une base de données SQL) est une autre bonne option, car elle permet en parallèle d'accès.klepto
pouvez utiliser à la fois spécialisé pickle formats (commenumpy
's) et de compression (si vous soucier de la taille et non pas la vitesse de l'accès aux données).klepto
vous donne la possibilité de stocker le dictionnaire avec "tout-en-un fichier" ou "une entrée par" fichier, et peut également tirer parti de multitraitement et multithread, ce qui signifie que vous pouvez enregistrer et charger des éléments dans le dictionnaire pour/depuis le backend en parallèle. Pour des exemples, voir les liens ci-dessus.OriginalL'auteur Mike McKerns
C'est un problème inhérent de cornichon,
qui est prévu pour une utilisation avec des quantités relativement faibles de
les données. La taille des dictionnaires, lorsqu'il est chargé dans la mémoire,
sont plusieurs fois plus grandes que sur le disque.
Après le chargement d'un cornichon fichier de 100 MO, vous pouvez très bien avoir
un dictionnaire de près de 1 GO.
Il y a quelques formules sur le web pour calculer les frais généraux, mais je ne peux que recommander d'utiliser certains
décent de base de données comme MySQL ou PostgreSQL pour de telles quantités de Données.
OriginalL'auteur inixmon
Je supose que vous utilisez 32bits Python et il a 4 go limitée. Vous devriez utiliser le 64 bits au lieu de 32 bits. J'ai essayer, mon marinés dict au-delà de 1,7 GO, et je n'ai pas eu aucun problème, sauf le temps passe plus.
OriginalL'auteur Jett