2016-11-03 1 views
1

Python (und Spyder) geben einen MemoryError zurück, wenn ich eine JSON-Datei lade, die 500Mo groß ist.MemoryError beim Laden einer JSON-Datei

Aber mein Computer hat einen 32Go RAM und der "Speicher", der von Spyder angezeigt wird, geht von 15% auf 19%, wenn ich versuche, es zu laden! Es scheint, dass ich viel mehr Platz hätte ...

Etwas, an das ich nicht gedacht habe?

+0

welches OS verwenden Sie? – Alex

+0

Windows 10, und ich benutze Spyder zum Programmieren und Ausführen. –

+0

Wenn Sie x32 Python verwenden, sind Sie auf 4 GB Speicher pro Prozess beschränkt. Sie treffen wahrscheinlich dieses Limit. – Alex

Antwort

5

500 MB JSON-Daten führen nicht zu 500 MB Speicherauslastung. Es wird zu einem Vielfachen davon führen. Um welchen Faktor handelt es sich genau, hängt von den Daten ab, aber ein Faktor von 10 - 25 ist nicht ungewöhnlich.

Zum Beispiel die folgende einfache JSON-String von 14 Zeichen (Bytes auf der Festplatte) zu einem Python-Objekt ist fast 25 mal größer (Python 3.6b3):

>>> import json 
>>> from sys import getsizeof 
>>> j = '{"foo": "bar"}' 
>>> len(j) 
14 
>>> p = json.loads(j) 
>>> getsizeof(p) + sum(getsizeof(k) + getsizeof(v) for k, v in p.items()) 
344 
>>> 344/14 
24.571428571428573 

Das ist, weil Python-Objekte einigen Aufwand erfordern ; Instanzen verfolgen die Anzahl der Referenzen auf sie, welchen Typ sie sind und ihre Attribute (wenn der Typ Attribute unterstützt) oder deren Inhalt (im Fall von Containern).

Wenn Sie mit der json integrierte Bibliothek, um diese Datei zu laden, wird es größer und größere Objekte aus den Inhalten aufbauen müssen, da sie analysiert werden, und an einem gewissen Punkt Ihr Betriebssystem wird sich weigern, mehr zu bieten Erinnerung. Das wird nicht bei 32GB sein, weil es eine Grenze pro Prozess gibt, wie viel Speicher verwendet werden kann, also eher bei 4GB. An diesem Punkt sind alle bereits erstellten Objekte wieder freigegeben, so dass am Ende die tatsächliche Speicherbelegung nicht so viel geändert haben muss.

Die Lösung besteht darin, entweder diese große JSON-Datei in kleinere Teilmengen aufzuteilen oder einen ereignisgesteuerten JSON-Parser wie ijson zu verwenden.

Ein ereignisgesteuerter JSON-Parser erstellt keine Python-Objekte für die gesamte Datei, nur für das aktuell analysierte Element, und benachrichtigt Ihren Code für jedes Element, das er mit einem Ereignis erstellt hat (z. B. ein Array starten) string, jetzt ein Mapping starten, das ist das Ende des Mappings, etc.). Sie können dann entscheiden, welche Daten Sie benötigen und behalten und welche Sie ignorieren müssen. Alles, was Sie ignorieren, wird wieder verworfen und die Speicherbelegung wird niedrig gehalten.

+0

Percect Antwort, wie immer von Ihnen;) Für den anderen, füge ich einen Link zu einer Erklärung, wie Ijson funktioniert: http://StackOverflow.com/ Fragen/40330820/Load-an-Element-mit-Python-von-Large-JSON-Datei –

+0

Und gibt es eine Möglichkeit, den Limit-Speicher pro Prozess zu ändern? –

+0

@ AgapeGal'lo: Ich bin mir nicht sicher, Sie können, es sieht für mich aus, dass Sie unter Windows nur die Grenzen * verringern * können: [Windows-Prozess (oder Benutzer) Speicherlimit festlegen] (// stackoverflow.com/q/192876). Ich bezweifle stark, dass das für Sie funktionieren wird. –

1

Also werde ich erklären, wie ich dieses Problem endlich gelöst habe. Die erste Antwort funktioniert. Aber Sie müssen wissen, dass das Laden von Elementen mit ijson pro Sekunde sehr lang sein wird ... und am Ende haben Sie die geladene Datei nicht.

So ist die wichtige Information, dass Windows Ihren Speicher pro Prozess auf 2 oder 4 GB begrenzen, abhängig davon, welche Fenster Sie verwenden (32 oder 64). Wenn Sie Pythonxy verwenden, ist das 2 GB (es existiert nur in 32). In beiden Fällen ist das sehr, sehr niedrig!

Ich löste dieses Problem durch die Installation eines virtuellen Linux in meinen Fenstern, und es funktioniert.Hier sind die wichtigsten Schritt, dies zu tun:

  1. installieren Virtual Box
  2. Ubuntu installieren (for exemple)
  3. installieren Python für Wissenschaftler auf dem Computer, like SciPy
  4. eine Share-Datei erstellen zwischen den zwei "Computer" (Sie finden Tutorial auf google)
  5. Führen sie den Code auf Ihrer ubuntu "Computer": es sould Arbeit;)

Hinweis: Vergessen Sie nicht, Ihrem virtuellen Computer ausreichend RAM und Arbeitsspeicher zu gewähren.

Das funktioniert für mich. Ich habe dieses "Speicherfehler" -Problem nicht mehr.

Ich poste hier dieses asnwer von there.

Verwandte Themen