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.
welches OS verwenden Sie? – Alex
Windows 10, und ich benutze Spyder zum Programmieren und Ausführen. –
Wenn Sie x32 Python verwenden, sind Sie auf 4 GB Speicher pro Prozess beschränkt. Sie treffen wahrscheinlich dieses Limit. – Alex