Warum Essiggurke Speicher essen?

Ich versuche damit umzugehen, große Mengen von eingelegten Daten durch kleine Stücke auf die Festplatte zu schreiben. Hier ist der Beispielcode:

from cPickle import *
from gc import collect

PATH = r'd:\test.dat'
@profile
def func(item):
    for e in item:
        f = open(PATH, 'a', 0)
        f.write(dumps(e))
        f.flush()
        f.close()
        del f
        collect()

if __name__ == '__main__':
    k = [x for x in xrange(9999)]
    func(k)

open () und close () werden innerhalb der Schleife platziert, um mögliche Ursachen für die Anhäufung von Daten im Speicher auszuschließen.

Zur Veranschaulichung des Problems füge ich die Ergebnisse der Speicherprofilerstellung bei, die mit dem Python 3d-Partymodul erstellt wurdenSpeicher_Profiler:

   Line #    Mem usage  Increment   Line Contents
==============================================
    14                           @profile
    15      9.02 MB    0.00 MB   def func(item):
    16      9.02 MB    0.00 MB       path= r'd:\test.dat'
    17
    18     10.88 MB    1.86 MB       for e in item:
    19     10.88 MB    0.00 MB           f = open(path, 'a', 0)
    20     10.88 MB    0.00 MB           f.write(dumps(e))
    21     10.88 MB    0.00 MB           f.flush()
    22     10.88 MB    0.00 MB           f.close()
    23     10.88 MB    0.00 MB           del f
    24                                   collect()

Während der Ausführung der Schleife tritt eine merkwürdige Speicherauslastung auf. Wie kann es beseitigt werden? Irgendwelche Gedanken?

Wenn die Menge der Eingabedaten zunimmt, kann das Volumen dieser zusätzlichen Daten sehr viel größer werden als das der Eingabe (upd: in der realen Aufgabe erhalte ich 300 + Mb)

Und eine weiter gefasste Frage: Welche Möglichkeiten gibt es, um mit großen Mengen an E / A-Daten in Python richtig zu arbeiten?

upd: Ich habe den Code so umgeschrieben, dass nur der Loop-Body übrig bleibt, um zu sehen, wann das Wachstum spezifisch stattfindet, und hier die Ergebnisse:

Line #    Mem usage  Increment   Line Contents
==============================================
    14                           @profile
    15      9.00 MB    0.00 MB   def func(item):
    16      9.00 MB    0.00 MB       path= r'd:\test.dat'
    17
    18                               #for e in item:
    19      9.02 MB    0.02 MB       f = open(path, 'a', 0)
    20      9.23 MB    0.21 MB       d = dumps(item)
    21      9.23 MB    0.00 MB       f.write(d)
    22      9.23 MB    0.00 MB       f.flush()
    23      9.23 MB    0.00 MB       f.close()
    24      9.23 MB    0.00 MB       del f
    25      9.23 MB    0.00 MB       collect()

Es scheint, als würde dumps () den Speicher auffressen. (Während ich eigentlich dachte, es wird schreiben ())

Antworten auf die Frage(1)

Ihre Antwort auf die Frage