2009-05-26 19 views
0

Ich habe ein Programm, das mehrere Dateien verarbeiten, und für jede Datei wird ein Bericht generiert. Der Bericht, der Teil generiert, ist eine separate Funktion, die einen Dateinamen annimmt und dann zurückgibt. Bei der Berichterstellung werden Zwischenteile im Speicher zwischengespeichert, da sie für mehrere Teile des Berichts verwendet werden können, um Neuberechnungen zu vermeiden.Python MemoryError - wie kann ich Objekt löschen

Wenn ich dieses Programm auf alle Dateien in einem Verzeichnis ausführen, wird es für eine Weile ausgeführt werden und dann mit einem MemoryError abstürzen. Wenn ich es dann im selben Verzeichnis erneut laufe, überspringt es alle Dateien, für die es erfolgreich einen Bericht erstellt hat, und macht weiter. Es wird ein paar Dateien verarbeiten, bevor es erneut abstürzt.

Nun, warum sind nach dem Methodenaufruf, der den Bericht generiert, nicht alle Ressourcen gelöscht oder zumindest für die Garbage Collection markiert? Es gibt keine Instanzen, und ich verwende keine globalen Objekte und nach jeder Dateiverarbeitung werden alle geöffneten Dateien geschlossen.

Gibt es Möglichkeiten für mich zu überprüfen, dass es keine zusätzlichen Verweise auf ein Objekt gibt? Gibt es eine Möglichkeit, die Speicherbereinigung in Python zu erzwingen?

Ein bisschen mehr Details über die Implementierung und Cache. Jeder Bericht enthält mehrere Elemente, jedes Element kann dann auf verschiedene Berechnungen zurückgreifen, jede Berechnung kann von anderen Berechnungen abhängen. Wenn eine Berechnung bereits durchgeführt wurde, möchte ich dies nicht mehr tun (die meisten sind teuer). Hier

ist eine gekürzte Version aus dem Cache:

class MathCache: 
    def __init__(self): self.cache = {} 
    def get(data_provider): 
     if not data_provider.id in self.cache: 
      self.cache[data_provider.id] = data_provider.get_value(self) 
     return self.cache[data_provider.id] 

eine Instanz davon erstellt wird, und dann auf jedes Element in dem Bericht übergeben. Diese Instanz wird nur in einer lokalen Referenz in der Berichterstellungsmethode gespeichert.

Alle data_provider erben von einer allgemeinen Klasse, die dazu dient, eine eindeutige ID für die Instanz basierend auf einem Hash-off-Konstruktorargumenten und Klassennamen zu erstellen. Ich gebe den MathCache weiter, da der data_provider sich auf andere Berechnungen verlassen kann.

+0

Ein bisschen mehr Code wäre hilfreich. Die "Zwischenteile sind im Speicher zwischengespeichert" ist vage - und wahrscheinlich die Ursache für Ihr Problem. Python verfügt über eine hervorragende Speicherbereinigung. Irgendwie verhindern Sie das. –

+0

Sind Sie sicher, dass die Zeilen 4 und 5 Ihres Beispiels richtig sind? Das sollte einen KeyError werfen. – bayer

+0

Ich denke du meinst self.cache [data_provide.id] = get_value (selbst) und nicht ".get_value (self)", richtig? – EOL

Antwort

Verwandte Themen