Unterschiede zwischen Java und PHP GC und warum

 JAVA GC-Verarbeitung

Es gibt zwei Möglichkeiten, festzustellen, ob Gras tot ist: Referenzzählung und Erreichbarkeitsanalyse

Der Grund, warum die Barrierefreiheitsanalyse für JAVA nützlicher ist, besteht darin, dass JAVA den strengen Anforderungen der Objektorientierung entspricht und jede Variable von einem Objekt umgeben ist, sodass jede Variable durch Durchlaufen des Objekts gefunden und schließlich beurteilt werden kann, ob dies der Fall ist referenziert;

Bei objektorientierten Objekten, die nach prozessorientierten Prinzipien wie PHP erstellt wurden, ist die Suche nach Variablenreferenzen jedoch fragmentierter, sodass das Hauptaugenmerk auf der Referenzzählung liegt.

Praktische Erinnerung: Wenn auf einer offenen Fläche das gesamte tote Gras entfernt wird ( Markierungsentfernung ), bleiben fragmentarisch kahle Stellen zurück. Wenn die Anzahl der kahlen Stellen zunimmt, verschieben Sie das gesamte Gras, das keine kahlen Stellen ist, auf eine neue offene Fläche ( Kopieren), Auf diese Weise werden das frei gewordene Land und die kahlen Stellen zu einem neuen offenen Raum kombiniert. Einige Gräser leben länger, andere kürzer. Es handelt sich um einen Generationsalgorithmus .

Der Garbage Collection-Mechanismus (Garbage Collection, GC) von Java ist eine Technologie zur automatischen Speicherverwaltung. Er ist für die Erkennung und Bereinigung von Objekten verantwortlich, auf die nicht mehr verwiesen wird, um Speicher freizugeben und Speicherlecks zu verhindern. In Java müssen Entwickler Speicher nicht manuell freigeben, da dies automatisch vom Garbage Collector erfolgt. Der Garbage-Collection-Mechanismus von Java basiert hauptsächlich auf den folgenden zwei Prinzipien:

  1. Referenzzählung (Referenzzählung) : Dies ist eine einfache Garbage-Collection-Methode, die die Referenzanzahl jedes Objekts verfolgt, um festzustellen, ob das Objekt recycelt werden kann. Wenn der Referenzzähler Null erreicht, gilt das Objekt als nicht mehr referenziert und kann recycelt werden. Diese Methode ist jedoch anfällig für Zirkelverweisprobleme und wird daher in Java nicht häufig verwendet.

  2. Erreichbarkeitsanalyse : Dies ist die Garbage-Collection-Methode, die hauptsächlich von Java verwendet wird. Es beginnt beim Stammobjekt (z. B. lokalen Variablen und statischen Variablen in der Hauptmethode) und verfolgt über die Referenzkette, ob auf das Objekt zugegriffen werden kann. Wenn ein Objekt nicht mehr über eine Referenzkette mit dem Stammobjekt verbunden ist, gilt das Objekt als nicht erreichbar und kann recycelt werden.

Im Folgenden sind die wichtigsten Garbage-Collection-Algorithmen in Java aufgeführt:

  1. Mark-and-Sweep-Algorithmus (Mark and Sweep) :

    • Dies ist der grundlegendste Garbage-Collection-Algorithmus.
    • Zunächst werden alle erreichbaren Objekte durch eine Erreichbarkeitsanalyse markiert.
    • Anschließend wird der gesamte Heap gescannt und nicht markierte Objekte bereinigt.
    • Das Problem bei diesem Algorithmus besteht darin, dass er zu einer Speicherfragmentierung führt, die dazu führen kann, dass der Heap-Speicher diskontinuierlich ist und sich somit auf die Programmleistung auswirkt.
  2. Kopieralgorithmus (Kopieren) :

    • Dieser Algorithmus unterteilt den Heap-Speicher in zwei Bereiche: halb belegt und halb leer.
    • Es markiert zunächst den verwendeten Bereich, kopiert dann die verbleibenden Objekte in den leeren Bereich und bereinigt schließlich den verwendeten Bereich.
    • Der Vorteil dieses Algorithmus besteht darin, dass er Speicherfragmentierungsprobleme vermeidet, aber zusätzlichen Speicher zum Kopieren von Objekten benötigt.
  3. Mark and Compact-Algorithmus (Mark and Compact) :

    • Dieser Algorithmus vereint die Vorteile von Mark-Sweep- und Copy-Algorithmen.
    • Zuerst markiert es erreichbare Objekte, komprimiert sie dann an einem Ende des Heaps und bereinigt Müllobjekte am anderen Ende des Heaps.
    • Dieser Algorithmus reduziert auch die Speicherfragmentierung, erfordert jedoch keinen zusätzlichen Speicher.
  4. Generationsalgorithmus (Generational) :

    • Dieser Algorithmus unterteilt den Heap basierend auf dem Alter der Objekte in verschiedene Generationen.
    • Objekte der jungen Generation haben im Allgemeinen einen kürzeren Lebenszyklus und Objekte der alten Generation haben einen längeren Lebenszyklus.
    • Die Müllabfuhr findet in der jungen Generation häufig statt, in der alten Generation seltener.
    • Dieser Algorithmus nutzt die Eigenschaften des Objekts und verbessert die Recyclingeffizienz.

PHPs GC-Handhabung

PHP verwendet die Referenzzählung (Reference Counting) als Hauptmechanismus für die Garbage Collection. Jede Variable und jedes Objekt verfügt in PHP über einen Referenzzähler, mit dem die Referenzbeziehung des Objekts verfolgt wird. Wenn der Referenzzähler einer Variablen oder eines Objekts auf Null sinkt, gilt es als nicht mehr referenziert und kann durch Garbage Collection erfasst werden.

Das Folgende ist das grundlegende Funktionsprinzip des Garbage Collection-Mechanismus für die Referenzzählung in PHP:

  1. Referenzzähler : Immer wenn eine Variable oder ein Objekt auf eine andere Variable oder ein anderes Objekt verweist, wird der Referenzzähler um 1 erhöht. Wenn eine Variable nicht mehr auf ein Objekt verweist, wird der Referenzzähler um 1 dekrementiert. Dieser Zähler wird in Echtzeit aktualisiert und spiegelt den aktuellen Referenzstatus des Objekts wider.

  2. Nicht erreichbare Objekte recyceln : Der Garbage Collector überprüft regelmäßig den Referenzzähler und findet Objekte mit einem Referenzzähler von Null. Diese Objekte gelten als nicht mehr referenziert und der Speicher kann sicher zurückgewonnen werden.

  3. Zirkelverweisproblem : Der Garbage-Collection-Mechanismus für die Referenzzählung ist bei Zirkelverweisproblemen nicht sehr effektiv. Von einem Zirkelverweis spricht man, wenn eine Reihe von Objekten aufeinander verweisen, wodurch ihre Referenzanzahl niemals auf Null sinkt. Um dieses Problem zu lösen, führt PHP die zyklische Speicherbereinigung (Cycle Collector) ein, die regelmäßig Zirkelverweise erkennt und verarbeitet.

  4. Periodische Garbage Collection : Der periodische Garbage Collector ist dafür verantwortlich, Zirkelverweise zu erkennen und den durch diese Zirkelverweise eingeschlossenen Speicher freizugeben. Es wird in bestimmten Intervallen ausgeführt, identifiziert und verarbeitet Zirkelverweise und verhindert so Speicherlecks.

Pythons GC-Handhabung

 

Der Garbage Collection-Mechanismus (Garbage Collection, GC) von Python basiert hauptsächlich auf den beiden Kernprinzipien Referenzzählung und zyklische Garbage Collection zur automatischen Speicherverwaltung. Im Folgenden finden Sie eine detaillierte Beschreibung des Garbage-Collection-Mechanismus von Python:

  1. Referenzzählung :

    • Jedes Objekt in Python verfügt über einen Referenzzähler, der die Referenzbeziehungen des Objekts verfolgt.
    • Wenn auf ein Objekt verwiesen wird, erhöht sich sein Verweiszähler um 1, und wenn auf ein Objekt nicht mehr verwiesen wird, verringert sich sein Verweiszähler um 1.
    • Wenn der Referenzzähler auf Null sinkt, bedeutet dies, dass das Objekt nicht mehr von Variablen oder Datenstrukturen referenziert wird und durch Garbage Collection erfasst werden kann.
  2. Zyklische Speicherbereinigung :

    • Der Referenzzählmechanismus kann die meisten Fälle effektiv verarbeiten, aber er kann keine Zirkelreferenzen verarbeiten (zwei oder mehr Objekte verweisen aufeinander, um einen Ring zu bilden).
    • Um das Zirkelverweisproblem zu lösen, führte Python den Cycle Collector ein.
    • Der zirkuläre Garbage Collector überprüft regelmäßig das Referenzdiagramm, um nicht erreichbare zirkuläre Referenzen zu finden und zu bereinigen.
  3. Generationsbezogene Müllsammlung :

    • Die Garbage Collection von Python führt außerdem eine Generations-Garbage-Collection-Strategie ein, die Objekte in drei Generationen unterteilt: junge Generation, mittlere Generation und alte Generation.
    • Die meisten neu erstellten Objekte werden der jungen Generation zugeordnet. Wenn sie mehrere Runden der Speicherbereinigung überstehen, werden sie zur mittleren Generation und dann zur alten Generation befördert.
    • Die generationsbasierte Strategie nutzt das Lebenszyklusmuster des Objekts, um die Effizienz der Speicherbereinigung zu verbessern.
  4. Garbage-Collection-Zyklus :

    • Die Garbage Collection von Python läuft nicht kontinuierlich, sondern wird unter bestimmten Bedingungen ausgelöst.
    • Der Garbage Collector wird ausgeführt, wenn eine Reihe von Auslösebedingungen erfüllt sind, z. B. wenn die Anzahl der Objekte in der jungen Generation einen Schwellenwert überschreitet, Speicherzuweisungsanforderungen fehlschlagen usw.
    • Wenn die Auslösebedingungen erfüllt sind, führt der Garbage Collector eine oder mehrere Garbage Collection-Runden durch, um nicht erreichbare Objekte zu bereinigen.
  5. gcModul :

    • Python stellt ein gcModul zur manuellen Steuerung und Konfiguration des Garbage-Collection-Mechanismus bereit.
    • gcEntwickler können Funktionen im Modul verwenden, um die Garbage Collection manuell auszulösen, die Garbage Collection zu deaktivieren oder Garbage Collection-Parameter zu konfigurieren.

Unterschiede zwischen PHP GC und Python GC

PHP und Python sind zwei verschiedene Skriptsprachen mit einigen Unterschieden in ihren Garbage Collection (GC)-Algorithmen und -Strategien. Im Folgenden sind die Hauptunterschiede zwischen den GC-Algorithmen von PHP und Python aufgeführt:

Der GC-Algorithmus von PHP :

  1. Referenzzählung : PHP verwendet hauptsächlich die Referenzzählung, um den Speicher zu verwalten. Jede Variable und jedes Objekt verfügt über einen Referenzzähler. Wenn der Referenzzähler Null erreicht, wird die Variable oder das Objekt recycelt. Diese Methode ist einfach und in Echtzeit, aber anfällig für Zirkelverweisprobleme.

  2. Zyklische Garbage Collection : Um das Problem der Zirkelverweise zu lösen, hat PHP die zyklische Garbage Collection (Cycle Collector) eingeführt. Der periodische Garbage Collector überprüft regelmäßig die Referenzbeziehungen zwischen Objekten, um nicht mehr verwendeten Speicher freizugeben. Dies ist PHPs Lösung für Zirkelverweisprobleme.

  3. Zend Memory Manager : PHP verwendet Zend Memory Manager, um den Speicher zu verwalten. Es ist für die Speicherzuweisung und -freigabe sowie für die Nachverfolgung der Referenzzählung und Speicherbereinigung verantwortlich. Zend Memory Manager kann das Garbage-Collection-Verhalten über Konfigurationsparameter anpassen.

Pythons GC-Algorithmus :

  1. Referenzzählung und zyklische Speicherbereinigung : Python verwendet auch Referenzzählung, um Objektreferenzbeziehungen zu verfolgen. Aber im Gegensatz zu PHP implementiert Python auch einen zirkulären Garbage Collector, um zirkuläre Referenzen zu erkennen und zu verarbeiten.

  2. Generationsbasierte Garbage Collection : Die Garbage Collection von Python führt auch eine generationsübergreifende Garbage Collection-Strategie ein. Python unterteilt Objekte in drei Generationen: junge Generation, mittlere Generation und alte Generation. Neu erstellte Objekte werden in die junge Generation eingeordnet, und wenn sie eine bestimmte Anzahl von Garbage-Collection-Zyklen überstehen, werden sie in die mittlere Generation befördert und so weiter. Diese Strategie nutzt beobachtete Objektlebenszyklusmuster und verbessert die Effizienz der Speicherbereinigung.

  3. Garbage-Collection-Zyklus : Der Garbage Collector von Python wird nicht regelmäßig ausgeführt, sondern basierend auf Schwellenwerten und Triggerbedingungen ausgelöst. Spezifische Auslösebedingungen umfassen die Anzahl der Objekte der jungen Generation, die Raumbelegung der jungen Generation usw. Diese Strategie kann die Auswirkungen der Garbage Collection auf die Leistung verringern.

GC der GO-Sprache

Die Garbage Collection (GC) der Go-Sprache (oder kurz Golang) ist ein Mechanismus zur automatischen Speicherverwaltung, der darauf abzielt, den Aufwand der manuellen Speicherverwaltung für Entwickler zu verringern und die Programmzuverlässigkeit und -leistung zu verbessern. Der GC-Mechanismus der Go-Sprache weist die folgenden Merkmale und Prinzipien auf:

  1. Gleichzeitige Garbage Collection : Der GC der Go-Sprache ist gleichzeitig, was bedeutet, dass der Garbage Collector ausgeführt werden kann, während das Programm ausgeführt wird. Es verursacht keine Anwendungspausen (Stop-The-World) und eignet sich daher sehr gut für Anwendungen mit hohen Parallelitäts- und Echtzeitanforderungen.

  2. Generationsbezogene Speicherbereinigung : Der GC der Go-Sprache verwendet eine generationsübergreifende Speicherbereinigungsstrategie, um den Heapspeicher in drei Generationen zu unterteilen: die neue Generation, die mittlere Generation und die alte Generation. Neu zugewiesene Objekte werden normalerweise in die neue Generation eingeordnet, und Objekte, die lange überlebt haben, werden auf die mittlere und alte Generation aktualisiert. Diese Generationsstrategie verbessert die Effizienz der Speicherbereinigung.

  3. Mark-and-Sweep-Algorithmus : Der Go-Garbage Collector verwendet den Mark-and-Sweep-Algorithmus. Es markiert zunächst alle aktiven Objekte und löscht dann die nicht markierten Objekte. Dieser Algorithmus ist in der Lage, Zirkelverweise zu verarbeiten und nicht mehr verwendeten Speicher effizient zurückzugewinnen.

  4. Dreifarben-Notation : Die GC of Go-Sprache führt die Dreifarben-Notation ein und markiert Objekte als weiß, schwarz und grau. Schwarz steht für als aktiv markierte Objekte, Weiß für nicht markierte Objekte und Grau für ausstehende Objekte. Dieser Ansatz trägt dazu bei, die Markierungs- und Reinigungsphasen zu reduzieren.

  5. Zeitsteuerung für die Garbage Collection : Der Garbage Collector der Go-Sprache kann die Zeit und Häufigkeit der Garbage Collection durch Festlegen von Umgebungsvariablen steuern. Dadurch können Entwickler je nach den Anforderungen der Anwendung Anpassungen vornehmen, um Leistung und Speichernutzung in Einklang zu bringen.

  6. Optimierung der Speicherzuweisung : Das Laufzeitsystem von Go enthält außerdem einen Speicherzuweiser, der für kleine und große Objekte optimiert ist, um die Speicherfragmentierung zu reduzieren und die Zuweisungsleistung zu verbessern.

In welchen Szenarien werden Zirkelverweise verwendet?

Ein Zirkelbezug bezieht sich auf zwei oder mehr Objekte, die aufeinander verweisen und so eine Zirkelbezugsbeziehung bilden. Diese Situation ist normalerweise nicht beabsichtigt, sondern ein Fehler oder eine schlecht geplante Situation. Obwohl von Zirkelverweisen im Allgemeinen abgeraten wird, gibt es bestimmte Szenarien, in denen sie erforderlich sein können, insbesondere bei bestimmten Programmiermodellen oder -designs:

  1. Zirkelverweise in Datenstrukturen : In manchen Datenstrukturen sind Zirkelverweise beabsichtigt. Beispielsweise enthält jeder Knoten in einer doppelt verknüpften Liste Verweise auf den vorherigen und nachfolgenden Knoten, sodass sie einen Zirkelverweis bilden. Diese Datenstruktur ist in bestimmten Situationen sehr nützlich.

  2. Diagrammdatenstruktur : Ein Diagramm ist eine Datenstruktur, die aus Knoten und Kanten besteht, wobei zwischen den Knoten Zirkelbezüge bestehen können. Diagrammdatenstrukturen werden häufig zur Darstellung von Netzwerken, Beziehungen und komplexen Datenassoziationen verwendet. In diesem Fall sind Zirkelverweise erforderlich.

  3. Beobachtermuster : Im Beobachtermuster kann es zirkuläre Referenzen zwischen dem Subjektobjekt (Subjekt) und dem Beobachterobjekt (Observer) geben. Das Themenobjekt muss das Beobachterobjekt über Aktualisierungen informieren, und das Beobachterobjekt muss normalerweise auf das Themenobjekt verweisen, um die Registrierung aufzuheben. In diesem Fall sind Zirkelverweise gerechtfertigt.

  4. Ressourcenverwaltung : Einige Ressourcen erfordern Verweise auf ihre Inhaber. Beispielsweise muss ein Objekt möglicherweise auf eine geöffnete Datei, eine Datenbankverbindung oder eine Netzwerkverbindung verweisen. In diesem Fall kann die Ressource von mehreren Objekten gehalten werden und einen Zirkelverweis bilden, um sicherzustellen, dass die Ressource nicht geschlossen wird, wenn kein Objekt auf sie verweist.

Ein Fall von Javascript-Zirkelverweis

class Subject {
  constructor() {
    this.observers = [];
  }

  addObserver(observer) {
    this.observers.push(observer);
  }

  notify(message) {
    this.observers.forEach(observer => {
      observer.update(message);
    });
  }
}

class Observer {
  constructor(name) {
    this.name = name;
  }

  update(message) {
    console.log(`${this.name} received message: ${message}`);
  }
}

const subject = new Subject();
const observer1 = new Observer("Observer 1");
const observer2 = new Observer("Observer 2");

subject.addObserver(observer1);
subject.addObserver(observer2);

observer1.subject = subject; // 主题引用了观察者
observer2.subject = subject;

subject.notify("Hello, observers!");

Im Beobachtermuster beziehen sich Beobachter normalerweise auf Subjektobjekte für die folgenden Zwecke:

  1. Zugriff auf Subjektdaten : Beobachter müssen auf die Daten oder den Status des Subjektobjekts zugreifen, um entsprechende Vorgänge auszuführen. Durch die Referenzierung des Themenobjekts können Beobachter leicht Informationen zum Thema erhalten.

  2. Auf Veränderungen im Subjekt reagieren : Die Hauptaufgabe des Beobachters besteht darin, auf Veränderungen im Zustand des Subjektobjekts zu reagieren. Durch Verweis auf das Themenobjekt können sich Beobachter registrieren und Benachrichtigungen vom Thema erhalten, damit sie wissen, wann und wie sie sich selbst aktualisieren müssen.

  3. Stellen Sie eine lose Kopplungsbeziehung zum Subjekt her : Die Bezugnahme auf das Subjektobjekt trägt dazu bei, eine lose Kopplungsbeziehung zwischen dem Beobachter und dem Subjektobjekt herzustellen. Beobachter müssen die internen Implementierungsdetails des Subjektobjekts nicht kennen, sie müssen lediglich auf die Zustandsänderungen des Subjekts achten.

Guess you like

Origin blog.csdn.net/wangsenling/article/details/132734030