Dieser Artikel bringt Ihnen relevantes Wissen über Python, das hauptsächlich verwandte Probleme mit CPythons Garbage Collector vorstellt, einer integrierten Methode von Python, um das Zirkelverweisproblem zu lösen .
【Verwandte Empfehlung: Python3-Video-Tutorial】
CPythons Garbage Collector (als GC bezeichnet) ist Pythons integrierte Methode zur Lösung des Zirkelverweisproblems. Standardmäßig läuft es immer im Hintergrund und entfaltet von Zeit zu Zeit seine Wirkung, sodass Sie sich keine Sorgen machen müssen, dass Zirkelverweise Ihren Speicher verstopfen.
Der Garbage Collector dient dazu, Zirkelverweisobjekte aus dem Arbeitsspeicher von CPython zu finden und zu entfernen. Dies geschieht auf folgende Weise.
Erkennen Sie zirkulär referenzierte Objekte
Rufen Sie die letzte __del__-Methode
auf, die die Zeiger von jedem Objekt entfernt (um das Schleifenproblem zu lösen), nur wenn die Schleife nach Schritt 2 immer noch verwaist ist. Das
Nachdem dieser Vorgang abgeschlossen ist, hat jedes Objekt, das sich zuvor in der Schleife befand, nun einen Referenzzähler von 0, sodass dieses Objekt aus dem Speicher gelöscht wird.
Obwohl es automatisch funktioniert, können wir es tatsächlich als Modul aus der Standardbibliothek importieren. Hier ist ein Beispiel:
import gc
Der Garbage Collector von CPython verfolgt verschiedene Objekte, die im Speicher vorhanden sind – aber nicht alle Objekte. Wir können einige Objekte instanziieren und prüfen, ob der Garbage Collector sie sammelt.
>>> gc.is_tracked("a string") False >>> gc.is_tracked(["a", "list"]) True
Wenn ein Objekt Zeiger enthalten kann, gibt ihm dies die Fähigkeit, Teil einer zirkulären Referenzstruktur zu sein – und genau dafür gibt es Garbage-Detektoren, um sie zu erkennen und zu zerstören. In Python werden solche Objekte oft „Containerobjekte“ genannt.
Der Garbage Collector muss also über alle Objekte Bescheid wissen, die möglicherweise als Teil eines Zirkelverweises vorhanden sind. Strings können dies nicht, daher wird „ein String“ nicht vom Garbage Collector verfolgt. Listen können (wie wir gesehen haben) Zeiger enthalten, sodass ['a', 'list'] verfolgt wird.
Alle Instanzen benutzerdefinierter Klassen werden ebenfalls vom Garbage Collector verfolgt, da wir jederzeit beliebige Eigenschaften (Zeiger) für sie festlegen können.
>>> Wade = MyNameClass("Wade") >>> gc.is_tracked(Wade) True
Der Garbage Collector kennt also alle Objekte, die Zirkelverweise bilden können. Woher weiß es, ob ein Zirkelverweis gebildet wurde?
Es kennt auch alle Zeiger in jedem Objekt und weiß, wohin sie zeigen. Wir können diese Aktion sehen.
>>> my_list = ["a", "list"] >>> gc.get_referents(my_list) ['list', 'a']
Die get_referents-Methode (auch als Traversal-Methode bekannt) empfängt ein Objekt und gibt eine Liste der darin enthaltenen Objektzeiger (seine Referenzen) zurück. Die obige Liste enthält also Zeiger auf jedes ihrer Elemente, bei denen es sich um Zeichenfolgen handelt.
Schauen wir uns die Methode get_referents in einer Schleife von Objekten an (allerdings noch kein Zirkelverweis, da auf die Objekte weiterhin aus dem Namespace zugegriffen werden kann).
>>> jane = MyNamedClass("Jane") >>> bob = MyNamedClass("Bob") >>> jane.friend = bob >>> bob.friend = jane >>> gc.get_referents(bob) [{'name': 'bob', 'friend': <__main__.MyNamedClass object at 0x7ff29a095d60>}, <class '__main__
In dieser Schleife können wir sehen, dass das Objekt, auf das Bob zeigt, Zeiger auf Folgendes enthält: sein Eigenschaftenwörterbuch, das Bobs Namen (Bob) und seine Freunde enthält (die MyNamedClass-Instanz, auf die auch Jane zeigt). Das Bob-Objekt verfügt auch über einen Zeiger auf das Klassenobjekt selbst, da bob.class dieses Klassenobjekt zurückgibt.
Wenn der Garbage Collector ausgeführt wird, prüft er, ob jedes Objekt, das ihm bekannt ist (d. h. jedes Objekt, das True zurückgibt, wenn Sie gc.is_tracked aufrufen), vom Namespace aus erreichbar ist. Dies geschieht durch die Verfolgung aller Zeiger aus dem Namespace, auf Zeiger in den Objekten, auf die diese Zeiger verweisen usw., bis eine Gesamtansicht aller Dinge erstellt wurde, auf die über den Code zugegriffen werden kann.
Wenn der GC danach feststellt, dass einige Objekte aus dem Namespace nicht erreichbar sind, kann er diese Objekte löschen.
Denken Sie daran, dass alle Objekte, die sich noch im Speicher befinden, einen Referenzzähler ungleich Null haben müssen, andernfalls werden sie aufgrund des Referenzzählers gelöscht. Für Objekte, die nicht erreichbar sind, aber dennoch einen Referenzzähler ungleich Null haben, müssen sie Teil eines Zirkelverweises sein, weshalb uns die Möglichkeit, dass dies geschieht, so wichtig ist.
Kehren wir zur Referenzschleife Jane und Bob zurück und verwandeln diese Schleife in eine Schleifenisolation, indem wir den Zeiger aus dem Namespace entfernen.
>>> del jane >>> del bob
Jetzt verstehen wir genau die Situation, die der Garbage Collector lösen soll. Wir können die manuelle Speicherbereinigung auslösen, indem wir gc.collect() aufrufen.
>>> gc.collect() Deleting Bob! Deleting Jane! 4
Standardmäßig führt der Garbage Collector diese Aktion von Zeit zu Zeit automatisch aus (da während der CPython-Laufzeit immer mehr Objekte erstellt und zerstört werden).
Im obigen Codeausschnitt enthält die Ausgabe, die wir sehen, die print-Anweisung der __del__-Methode von MyNamClass mit einer Zahl am Ende – in diesem Fall 4. Diese Zahl wird vom Garbage Collector selbst ausgegeben und sagt uns, wie viele Objekte entfernt wurden.
【Verwandte Empfehlungen: Python3-Video-Tutorial】
Das obige ist der detaillierte Inhalt vonErfahren Sie in einem Artikel mehr über den Garbage Collector in CPython. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!