Ich habe ein Skript mit langer Laufzeit, das, wenn es lange genug ausgeführt wird, den gesamten Speicher auf meinem System belegt.
Ohne auf Details zum Skript einzugehen, habe ich zwei Fragen:
- Gibt es "Best Practices", die dazu beitragen, das Auftreten von Lecks zu verhindern?
- Welche Techniken gibt es, um Speicherlecks in Python zu debuggen?
python
debugging
memory-management
memory-leaks
Fragsworth
quelle
quelle
__del__
Methoden aufgelistet , auf die bis auf ihren Zyklus nicht mehr verwiesen wird. Der Zyklus kann aufgrund von Problemen mit nicht unterbrochen werden__del__
. Repariere es!Antworten:
Schauen Sie sich diesen Artikel an: Aufspüren von Python-Speicherlecks
Beachten Sie außerdem, dass für das Garbage Collection-Modul tatsächlich Debug-Flags gesetzt werden können. Schauen Sie sich die
set_debug
Funktion an. Schauen Sie sich außerdem diesen Code von Gnibbler an, um die Objekttypen zu ermitteln, die nach einem Aufruf erstellt wurden.quelle
Ich habe die meisten zuvor genannten Optionen ausprobiert, fand dieses kleine und intuitive Paket jedoch das beste: Pympler
Es ist ganz einfach, Objekte zu verfolgen, die nicht durch Müll gesammelt wurden. Überprüfen Sie dieses kleine Beispiel:
Paket installieren über
pip install pympler
Die Ausgabe zeigt Ihnen alle hinzugefügten Objekte sowie den von ihnen verbrauchten Speicher.
Beispielausgabe:
Dieses Paket bietet eine Reihe weiterer Funktionen. Überprüfen Sie die Dokumentation des Pymplers , insbesondere den Abschnitt Identifizieren von Speicherlecks .
quelle
pympler
dies langsam sein kann . Wenn Sie etwas in Echtzeit ausführen, kann dies Ihre Anwendungsleistung vollständig beeinträchtigen.Lassen Sie mich das von mir erstellte mem_top- Tool empfehlen
Es hat mir geholfen, ein ähnliches Problem zu lösen
Es zeigt sofort die Hauptverdächtigen für Speicherlecks in einem Python-Programm
quelle
Das Tracemalloc-Modul wurde ab Python 3.4 als integriertes Modul integriert und ist anscheinend auch für frühere Versionen von Python als Bibliothek eines Drittanbieters verfügbar (hat es jedoch nicht getestet).
Dieses Modul kann die genauen Dateien und Zeilen ausgeben, die den meisten Speicher zugewiesen haben. IMHO, diese Informationen sind unendlich wertvoller als die Anzahl der zugewiesenen Instanzen für jeden Typ (was in 99% der Fälle eine Menge Tupel darstellt, was ein Hinweis ist, aber in den meisten Fällen kaum hilft).
Ich empfehle Ihnen, Tracemalloc in Kombination mit Pyrasit zu verwenden . Wenn Sie das Top-10-Snippet 9 Mal von 10 Mal in einer Pyrasit-Schale ausführen , erhalten Sie genügend Informationen und Hinweise, um das Leck innerhalb von 10 Minuten zu beheben. Wenn Sie die Leckursache immer noch nicht finden können, gibt Ihnen die Pyrasit-Schale in Kombination mit den anderen in diesem Thread genannten Werkzeugen wahrscheinlich auch weitere Hinweise. Sie sollten sich auch alle zusätzlichen Helfer von Pyrasite ansehen (z. B. den Memory Viewer).
quelle
Sie sollten sich insbesondere Ihre globalen oder statischen Daten (langlebige Daten) ansehen.
Wenn diese Daten ohne Einschränkung wachsen, können auch in Python Probleme auftreten.
Der Garbage Collector kann nur Daten erfassen, auf die nicht mehr verwiesen wird. Ihre statischen Daten können jedoch Datenelemente verbinden, die freigegeben werden sollen.
Ein weiteres Problem können Speicherzyklen sein, aber zumindest theoretisch sollte der Garbage Collector Zyklen finden und eliminieren - zumindest solange sie nicht an langlebige Daten gebunden sind.
Welche Arten von langlebigen Daten sind besonders problematisch? Sehen Sie sich Listen und Wörterbücher genau an - sie können unbegrenzt wachsen. In Wörterbüchern sehen Sie möglicherweise sogar keine Probleme, da beim Zugriff auf Wörterbücher die Anzahl der Schlüssel im Wörterbuch für Sie möglicherweise nicht besonders gut sichtbar ist ...
quelle
Um Speicherlecks für lange laufende Prozesse zu erkennen und zu lokalisieren, z. B. in Produktionsumgebungen, können Sie jetzt Stackimpact verwenden . Es verwendet Tracemalloc darunter. Weitere Infos in diesem Beitrag .
quelle
Achten Sie bei Best Practices auf rekursive Funktionen. In meinem Fall stieß ich auf Probleme mit der Rekursion (wo es keine geben musste). Ein vereinfachtes Beispiel dafür, was ich tat:
Wenn Sie auf diese rekursive Weise arbeiten, wird die Speicherbereinigung nicht ausgelöst und die Reste der Funktion werden nicht entfernt, sodass die Speichernutzung jedes Mal zunimmt.
Meine Lösung bestand darin, den rekursiven Aufruf aus my_function () zu ziehen und main () zu behandeln, wann er erneut aufgerufen werden soll. Auf diese Weise endet die Funktion auf natürliche Weise und räumt nach sich selbst auf.
quelle
Sie sind sich nicht sicher über "Best Practices" für Speicherlecks in Python, aber Python sollte seinen eigenen Speicher durch seinen Garbage Collector löschen. Also würde ich hauptsächlich nach einer kreisförmigen Liste von Kurzfilmen suchen, da diese nicht vom Müllsammler abgeholt werden.
quelle
Dies ist kein erschöpfender Rat. Das Wichtigste beim Schreiben mit dem Gedanken, zukünftige Speicherlecks (Schleifen) zu vermeiden, ist jedoch sicherzustellen, dass alles, was einen Verweis auf einen Rückruf akzeptiert, diesen Rückruf als schwache Referenz speichert.
quelle