2 Stimmen

Kann ich den Heap in einem Python-Skript defragmentieren?

Ich führe ein Malware-Analyseexperiment in Python durch und muss ein großes Objekt erstellen (512 MB, denke ich). Beim lokalen Testen (64-Bit-System) gibt es kein Problem, aber wenn ich versuche, es auf einem Remote-32-Bit-System auszuführen (damit der Prozess einen Stack von max. 4 GB hat), erhalte ich einen MemoryError (der Stack-Trace gibt nicht viele Informationen). Die große Zuweisung ist:

from sklearn.grid_search import GridSearchCV
...
model = GridSearchCV(svm.LinearSVC(), {'C':numpy.logspace(-3,3,7)})
model.fit(train_vectors, labels)

Ich habe den Systemadministrator nach dem System gefragt und er sagt mir, dass wahrscheinlich die vorherigen Zuweisungen den Heap fragmentiert haben, sodass die große Zuweisung nicht mehr möglich ist.

Ich habe versucht, gc.collect() direkt vor dem Aufruf auszuführen, der die große Zuweisung verursacht, aber das Problem bleibt bestehen.

Ich glaube nicht, dass es eine Möglichkeit gibt, die große Zuweisung kleiner zu machen.

Irgendwelche Vorschläge, wie ich den Heap defragmentieren könnte?

Bearbeiten: Ich habe es geschafft, die Trainingsvektoren viel kleiner zu machen. Jetzt muss ich sehen, ob die Malware-Erkennungstechnik noch funktioniert. Wenn das der Fall ist, sollte mein Problem gelöst sein. Der Grund war, dass die Vektoren numpy-Arrays waren und nur die Verwendung der Funktion tolist() sie viel kleiner machte.

Bearbeiten 2: Nur die Verwendung von Listen (von Floats) reichte nicht aus. Da die Werte sowieso Ganzzahlen waren, habe ich die Floats in Ganzzahlen umgewandelt, wodurch die Vektoren etwas kleiner wurden. Dies hatte einen großen Einfluss auf den Speicherverbrauch. Ich habe die Vektoren mit cPickle gespeichert und unter Verwendung desselben Moduls abgerufen. Ich vermute, dass in diesem Modul irgendwo ein Fehler vorliegt, der einen Speicherfehler verursacht, wenn Floats geladen werden, der bei Ganzzahlen nicht auftritt.

Zusammenfassung: Ich habe keinen Weg gefunden, den Heap zu defragmentieren, aber ich konnte das Problem mithilfe von Memory-Profiler (den ich am besten fand) und Heapy lokalisieren. Ich habe das Problem gelöst, indem ich die Vektoren kleiner gemacht habe und den Datentyp in Ganzzahlen geändert habe (anstelle von Floats). Ich vermute, dass das von mir verwendete cPickle-Modul zum Speichern/Laden der Vektoren einen Speicherleck bei Verwendung von Floats aufweist, weshalb mir der Speicher ausgegangen ist.

1voto

A. Rama Punkte 913

Sie sollten einen Speicherprofiler verwenden.

Von Welcher Python-Speicherprofiler wird empfohlen? :

Heapy

memory_profiler

PySizer

Dowser

oder sogar die objgraph Bibliothek

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X