Einführung
Speicherverwaltung ist der Prozess der effizienten Zuweisung, Freigabe und Koordinierung von Speicher, damit alle verschiedenen Prozesse reibungslos ablaufen und optimal auf die verschiedenen Systemressourcen zugreifen können. Zur Speicherverwaltung gehört auch das Bereinigen des Speichers von Objekten, auf die nicht mehr zugegriffen wird.
In Python ist der Speichermanager für diese Art von Aufgaben verantwortlich, indem er regelmäßig ausgeführt wird, um den Speicher aufzuräumen, zuzuweisen und zu verwalten. Im Gegensatz zu C, Java und anderen Programmiersprachen verwaltet Python Objekte mit Hilfe der Referenzzählung. Das bedeutet, dass der Speichermanager die Anzahl der Referenzen auf jedes Objekt im Programm verfolgt. Wenn die Anzahl der Referenzen eines Objekts auf Null sinkt, was bedeutet, dass das Objekt nicht mehr verwendet wird, gibt der Garbage Collector (Teil des Speichermanagers) automatisch den Speicher für das betreffende Objekt frei.
Der Benutzer muss sich nicht um die Speicherverwaltung kümmern, da der Prozess der Zuweisung und Freigabe von Speicher vollautomatisch erfolgt. Der wiedergewonnene Speicher kann von anderen Objekten genutzt werden.
Python Garbage Collection
Wie bereits erläutert, löscht Python Objekte, die im Programm nicht mehr referenziert werden, um Speicherplatz freizugeben. Dieser Prozess, bei dem Python Speicherblöcke freigibt, die nicht mehr verwendet werden, wird Garbage Collection genannt. Der Python Garbage Collector (GC) läuft während der Programmausführung und wird ausgelöst, wenn die Anzahl der Referenzen auf Null sinkt. Die Anzahl der Referenzen erhöht sich, wenn ein Objekt einen neuen Namen erhält oder in einen Container wie ein Tupel oder ein Wörterbuch eingefügt wird. Ebenso verringert sich der Referenzzähler, wenn der Verweis auf ein Objekt neu zugewiesen wird, wenn der Verweis des Objekts aus dem Geltungsbereich herausgeht oder wenn ein Objekt gelöscht wird.
Der Speicher ist ein Heap, der Objekte und andere im Programm verwendete Datenstrukturen enthält. Die Zuweisung und Freigabe dieses Heap-Speicherplatzes wird vom Python-Speicher-Manager durch die Verwendung von API-Funktionen gesteuert.
Python-Objekte im Speicher
Jede Variable in Python fungiert als ein Objekt. Objekte können entweder einfach sein (mit Zahlen, Strings usw.) oder Container (Wörterbücher, Listen oder benutzerdefinierte Klassen). Außerdem ist Python eine dynamisch typisierte Sprache, was bedeutet, dass wir die Variablen oder ihre Typen nicht deklarieren müssen, bevor wir sie in einem Programm verwenden.
Zum Beispiel:
Wenn man sich die ersten beiden Zeilen des obigen Programms ansieht, ist das Objekt x
bekannt. Wenn wir das Objekt x
löschen und versuchen, es zu verwenden, erhalten wir eine Fehlermeldung, die besagt, dass die Variable x
nicht definiert ist.
Sie können sehen, dass die Garbage Collection in Python vollständig automatisiert ist und der Programmierer sich nicht darum kümmern muss, im Gegensatz zu Sprachen wie C.
Modifizieren des Garbage Collectors
Der Python Garbage Collector hat drei Generationen, in denen Objekte klassifiziert werden. Ein neues Objekt, das am Anfang seines Lebenszyklus steht, ist die erste Generation des Garbage Collectors. Wenn das Objekt die Garbage Collection überlebt, wird es in die nächste Generation verschoben. Jede der 3 Generationen des Garbage Collectors hat einen Schwellenwert. Wenn der Schwellenwert für die Anzahl der Zuweisungen abzüglich der Anzahl der De0allokationen überschritten wird, führt diese Generation eine Garbage Collection durch.
Frühere Generationen werden auch häufiger garbage collected als die höheren Generationen. Das liegt daran, dass neuere Objekte eher verworfen werden als alte Objekte.
Das gc
Modul enthält Funktionen, um den Schwellenwert zu ändern, einen Garbage-Collection-Prozess manuell auszulösen, den Garbage-Collection-Prozess zu deaktivieren, usw. Wir können die Schwellenwerte verschiedener Generationen des Garbage Collectors mit der Methode get_threshold()
überprüfen:
import gcprint(gc.get_threshold())
Beispielausgabe:
(700, 10, 10)
Wie Sie sehen, haben wir hier einen Schwellenwert von 700 für die erste Generation und jeweils 10 für die beiden anderen Generationen.
Wir können den Schwellenwert für die Auslösung der Garbage Collection mit der Methode set_threshold()
des Moduls gc
ändern:
gc.set_threshold(900, 15, 15)
Im obigen Beispiel haben wir den Schwellenwert für alle 3 Generationen erhöht. Durch die Erhöhung des Schwellenwerts wird die Häufigkeit der Ausführung des Garbage Collectors verringert. Normalerweise muss man sich als Entwickler nicht allzu viele Gedanken über die Garbage Collection von Python machen, doch kann dies bei der Optimierung der Python-Laufzeit für Ihr Zielsystem nützlich sein. Einer der Hauptvorteile ist, dass Pythons Garbage-Collection-Mechanismus viele Low-Level-Details für den Entwickler automatisch erledigt.
Warum manuelle Garbage-Collection durchführen?
Wir wissen, dass der Python-Interpreter Referenzen auf Objekte, die in einem Programm verwendet werden, aufzeichnet. In früheren Versionen von Python (bis Version 1.6) verwendete der Python-Interpreter nur den Mechanismus der Referenzzählung, um den Speicher zu verwalten. Wenn die Anzahl der Referenzen auf Null sinkt, gibt der Python-Interpreter den Speicher automatisch frei. Dieser klassische Mechanismus der Referenzzählung ist sehr effektiv, funktioniert aber nicht, wenn das Programm Referenzzyklen hat. Ein Referenzzyklus entsteht, wenn ein oder mehrere Objekte aufeinander verweisen und der Referenzzähler daher niemals Null erreicht.
Betrachten wir ein Beispiel.
>>> def create_cycle():... list = ... list.append(list)... return list... >>> create_cycle()]
Der obige Code erzeugt einen Referenzzyklus, in dem das Objekt list
auf sich selbst verweist. Folglich wird der Speicher für das Objekt list
nicht automatisch freigegeben, wenn die Funktion zurückkehrt. Das Problem des Referenzzyklus kann nicht durch Referenzzählung gelöst werden. Das Problem des Referenzzyklus kann jedoch gelöst werden, indem man das Verhalten des Garbage Collectors in der Python-Anwendung ändert.
Dazu können wir die Funktion gc.collect()
des Moduls gc
verwenden.
import gcn = gc.collect()print("Number of unreachable objects collected by GC:", n)
Die Funktion gc.collect()
gibt die Anzahl der Objekte zurück, die sie gesammelt und freigegeben hat.
Es gibt zwei Möglichkeiten, die manuelle Garbage Collection durchzuführen: zeitbasierte oder ereignisbasierte Garbage Collection.
Die zeitbasierte Garbage Collection ist ziemlich einfach: Die gc.collect()
-Funktion wird nach einem festen Zeitintervall aufgerufen.
Ereignisbasierte Garbage Collection ruft die Funktion gc.collect()
auf, nachdem ein Ereignis eingetreten ist (d.h. wenn die Anwendung beendet wird oder die Anwendung für eine bestimmte Zeitspanne inaktiv bleibt).
Lassen Sie uns die manuelle Garbage Collection anhand einiger Referenzzyklen verstehen.
Die Ausgabe sieht wie folgt aus:
Creating garbage...Collecting...Number of unreachable objects collected by GC: 8Uncollectable garbage:
Das obige Skript erstellt ein Listenobjekt, auf das eine Variable mit dem kreativen Namen list
verweist. Das erste Element des Listenobjekts verweist auf sich selbst. Die Anzahl der Verweise auf das Listenobjekt ist immer größer als Null, auch wenn es im Programm gelöscht wird oder sich außerhalb des Geltungsbereichs befindet. Daher wird das Objekt list
aufgrund der zirkulären Referenz nicht vom Garbage Collecting erfasst. Der Garbage-Collector-Mechanismus in Python prüft automatisch auf zirkuläre Referenzen und sammelt sie regelmäßig ein.
Im obigen Code haben wir die Objekte durch den Aufruf von gc.collect()
zwangsweise garbage collected, da die Referenzanzahl mindestens 1 beträgt und niemals 0 erreichen kann. Beachten Sie jedoch, dass Sie die Garbage Collection nicht häufig erzwingen sollten. Der Grund dafür ist, dass der GC auch nach dem Freigeben des Speichers Zeit benötigt, um die Eignung des Objekts für die Garbage Collection zu bewerten, was Prozessorzeit und Ressourcen beansprucht. Denken Sie auch daran, den Garbage Collector erst dann manuell zu steuern, wenn Ihre Anwendung vollständig gestartet ist.
Abschluss
In diesem Artikel haben wir besprochen, wie die Speicherverwaltung in Python durch Referenzzählung und Garbage-Collection-Strategien automatisch gehandhabt wird. Ohne Garbage Collection ist die Implementierung eines erfolgreichen Speicherverwaltungsmechanismus in Python unmöglich. Außerdem müssen sich Programmierer nicht um das Löschen von zugewiesenem Speicher kümmern, da dies vom Python-Speicherverwalter übernommen wird. Dies führt zu weniger Speicherlecks und besserer Leistung.