Ist es möglich, eine tatsächliche Speicher-Leck in Python, weil Sie Ihren code?
Habe ich nicht ein code-Beispiel, aber ich bin neugierig, ob es möglich ist, schreiben Sie Python code, dass die Ergebnisse im wesentlichen ein Speicher-Leck.
- Sie sollten klären: sprechen Sie über Speicherbelegung, nachdem der Prozess fertig ausgeführt wurde; und sprechen Sie über die Reine Python keine C Module?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist möglich, ja.
Es hängt davon ab, welche Art von Speicher-Leck Sie reden. In reinem python-code, es ist nicht möglich, zu "vergessen freie" Speicher, wie in C, aber es ist möglich, lassen Sie eine Referenz irgendwo hängen. Einige Beispiele:
eine unbehandelte traceback-Objekt ist, dass ein ganzer stack frame lebendig, auch wenn die Funktion nicht mehr ausgeführt wird
In diesem dummen Beispiel für ein Spiel, Schleife vielleicht, wir zugewiesen, 'tb', um einen lokalen. Wir hatten gute Absichten, aber diese tb-frame enthält Informationen über die stack-was war passiert in unserer handle_input den ganzen Weg hinunter zu dem, was diese genannt. Vorausgesetzt, Ihr Spiel Fort, 'tb' am Leben gehalten wird, auch in Ihrem nächsten Aufruf handle_input, und vielleicht für immer. Die docs für exc_info nun sprechen Sie über diese möglichen Zirkelbezug-Problem und empfehlen einfach nicht die Zuordnung
tb
wenn Sie nicht unbedingt benötigen. Wenn Sie brauchen, um einen traceback berücksichtigen, z.B.traceback.format_exc
speichern von Werten in einer Klasse oder einem globalen Rahmen statt der Instanz Umfang, und nicht es zu merken.
Dies kann geschehen, in heimtückischer Weise, aber oft geschieht, wenn Sie veränderlich definieren Typen in Ihrer Klasse Anwendungsbereich.
Im obigen Beispiel, sagen, Sie haben
Finden Sie wahrscheinlich diese bestimmten Fehler schnell, aber in diesem Fall stellen Sie einen änderbaren Wert in der Klasse Anwendungsbereich und obwohl Sie richtig Zugriff auf Instanz-Umfang, es ist tatsächlich "fallen durch" die class-Objekt's
__dict__
.Diese nur in bestimmten Kontexten wie holding-Objekte, die potenziell dazu führen, dass Dinge, die bewirken, dass Ihre Anwendung der Haufen wachsen immer, und würde Probleme verursachen, in, sagen wir, ein Produktions-web-Anwendung, nicht neu starten, die Prozesse gelegentlich.
Zyklische Referenzen in Klassen, die haben auch eine
__del__
Methode.Ironischerweise, die Existenz einer
__del__
macht es unmöglich für den zyklischen garbage collector-reinigen Sie ein Beispiel bis. Sagen Sie, dass Sie etwas hatten, wo Sie wollten einen Destruktor für die Finalisierung Zwecke:Nun dies funktioniert gut auf Ihre eigenen, und Sie können geführt werden, zu glauben, es ist ein guter steward von OS-Ressourcen, um sicherzustellen, die Steckdose wird 'entsorgt' von.
Jedoch, wenn ClientConnection hielt eine Referenz zu sagen,
User
und Nutzer gehalten, ein Verweis auf die Verbindung, die Sie könnten versucht sein, zu sagen, dass auf Bereinigung, wir haben Benutzer de-Verweis auf die Verbindung. Das ist eigentlich der Fehler, jedoch: die zyklische GC nicht wissen, die richtige Reihenfolge der Operationen und nicht reinigen Sie es bis.Die Lösung dafür ist, um sicherzustellen, dass Sie nicht Aufräumen auf sagen, trennen Sie Veranstaltungen, indem Sie einige Art in der Nähe, aber Namen, die Methode etwas anderes als
__del__
.schlecht umgesetzt, C-Erweiterungen, oder nicht richtig mit C-Bibliotheken, wie Sie sein sollen.
In Python, Sie Vertrauen in den garbage collector zu werfen Dinge Weg, die Sie nicht verwenden. Aber wenn du eine C-Erweiterung umschließt, die eine C-Bibliothek, die Mehrheit der Zeit, Sie sind dafür verantwortlich, dass Sie explizit geschlossen oder de-allocate-Ressourcen. Meist ist dies dokumentiert, aber ein python-Programmierer, der verwendet wird, um nicht zu tun, diese explizite de-Aufteilung kann wegwerfen der Griff (wie bei der Rückkehr aus einer Funktion oder was auch immer), die Bibliothek, ohne zu wissen, dass die Ressourcen gehalten werden.
Bereiche enthalten, die Verschlüsse, die enthalten eine ganze Menge mehr, als Sie haben könnte erwartet
In diesem erfundenen Beispiel den Anschein, dass wir über irgendeine Art von 'async' Anruf, rufen Sie uns wieder an
on_completed
wenn die DB-Aufruf erfolgt ist (könnte die Umsetzung habe schon verspricht, es endet mit dem gleichen Ergebnis).Was Sie vielleicht nicht wissen, ist, dass die
on_completed
Schließung bindet eine Referenz aufself
bei der Ausführung desself.profile
Zuordnung. Nun, vielleicht ist der DB-client verfolgt aktiv Abfragen und Verweise auf die Verschlüsse zu rufen, wenn Sie fertig sind (da es async) und sagen, es stürzt ab, aus welchem Grund auch immer. Wenn der DB-client nicht korrekt Bereinigung Rückrufe etc, in diesem Fall der DB-client verfügt nun über einen Verweis auf on_completed, die eine Referenz auf Benutzer, die hält ein_db
- Sie haben nun erstellt eine kreisförmige Referenz, die vielleicht nie gesammelt.(Auch ohne einen Zirkelbezug, die Tatsache, dass die Verschlüsse binden einheimische und auch Instanzen manchmal verursachen Werte, die Sie dachte wurden gesammelt, um sein Leben für eine lange Zeit, die könnte auch Steckdosen, clients, große Puffer, und ganze Bäume Dinge)
Standard-Parameter, die veränderliche Arten
Dies ist ein erfundenes Beispiel, aber man könnte geführt werden, zu glauben, dass der Standardwert von
a
wird eine leere Liste bedeutet Anhängen, um es, wenn es ist in der Tat ein Verweis auf die gleichen Liste. Dies wiederum könnte dazu führen, dass grenzenlose Wachstum, ohne zu wissen, dass Sie das getan hat.sys.last_traceback
hält eine Referenz auf die Letzte traceback und Informationen aussys.exc_info()
funktioniert ähnlich. Dies wird weiter kompliziert mit cross-language-bindings, etc... ich werde springen auf deine Frage und mehr beantworten.del foo
ist ausreichend, um freien Speicher zugewiesen, der durcha
. Ich sehe nicht ein memory-leak gibt!Die klassische definition eines Speicherlecks ist ein Speicher, der wurde einmal benutzt, und jetzt ist es nicht, aber wurde nicht zurückgefordert. Dass fast unmöglich, mit reinem Python-code. Aber als Antoine Punkte aus, kann man leicht den Effekt haben, verbrauchen alle Ihre Speicher versehentlich, indem Datenstrukturen zu wachsen, ohne gebunden, auch wenn Sie nicht brauchen, um die Daten herum.
Mit C-Erweiterungen, natürlich, Sie sind zurück, die in nicht verwalteten Territorium, und alles ist möglich.
Natürlich können Sie. Das typische Beispiel für ein memory leak ist, wenn Sie bauen einen cache, den Sie nie erröten manuell und hat keine automatische Ausweisung Politik.
Im Sinne der Verwaisung dar zugewiesenen Objekte, nachdem Sie nicht mehr gültig sind, weil Sie vergessen haben, freigeben, Sie, nicht; Python wird automatisch freigeben out-of-scope-Objekte (Garbage Collection). Aber in dem Sinne, dass @Antione reden, ja.
Da viele Module sind in C geschrieben , ja, es ist möglich, Speicherlecks.
stellen Sie sich vor Sie sind mit einem gui-malen zeichnen-Kontext (z.B. mit wxpython) , können Sie den Speicher-Puffer, aber wenn Sie vergessen haben, es zu veröffentlichen. haben Sie memory leaks...
in diesem Fall C++ - Funktionen von wx-api gewickelt werden, um python.
einen größeren falsche Verwendung , stellen Sie sich vor überlastung diese wx-widgets die Methoden in python... memoryleaks versichert.
Erstelle ich ein Objekt mit einem schweren Attribut zu zeigen, in den Prozess Speichernutzung.
Dann Erzeuge ich ein dictionary, die sich selbst für eine große Anzahl von Zeiten.
Dann habe ich ein Objekt löschen, und bitten GC zu sammeln garrbage. Es sammelt keiner.
Dann überprüfe ich den Prozess RAM-footprint - ist es das gleiche.
Hier gehen Sie, Speicherleck!