Heim  >  Artikel  >  Backend-Entwicklung  >  Erklären Sie den PHP-Garbage-Collection-Mechanismus anhand von Beispielen im Detail

Erklären Sie den PHP-Garbage-Collection-Mechanismus anhand von Beispielen im Detail

王林
王林nach vorne
2019-08-29 13:55:312953Durchsuche

PHP-Garbage-Collection-Mechanismus :

1. PHP kann den Speicher automatisch verwalten und unnötige Objekte löschen, hauptsächlich mithilfe der Referenzzählung

2 ref_count ist ein Referenzzähler, der angibt, auf wie viele Variablen auf diesen zval verwiesen wird. Wenn er 0 ist, wird er zerstört. is_ref identifiziert, ob das &-Adresszeichen zum Erzwingen einer Referenz verwendet wird

3. Um das Problem von Speicherlecks bei zirkulären Referenzen zu lösen, wird ein synchroner Zyklus-Recycling-Algorithmus verwendet.

Wenn beispielsweise ein Array oder Objekt zyklisch auf sich selbst verweist und das Array zurücksetzt und refcount-1 immer noch größer als 0 ist, wird dies als verdächtiger Müll betrachtet, durchquert und die Löschung von refcount-1 simuliert Wenn es 0 ist, löschen Sie es. Wenn es nicht 0 ist, stellen Sie den Generierungsprozess von hartnäckigem Müll wieder her:

<?php
    $a = "new string";
?>
a: (refcount_gc=1, is_ref_gc=0)=&#39;new string&#39;

Wenn $a einer anderen Variablen zugewiesen wird, wird der refcount_gc des $a entsprechenden zval erhöht um 1

<?php
    $a = "new string";
    $b = $a;
?>

Zu diesem Zeitpunkt lauten die internen Speicherinformationen, die den Variablen $a und $b entsprechen, $a und $b zeigen gleichzeitig auf eine Zeichenfolge „neue Zeichenfolge“, und ihr Refcount wird 2a,b: (refcount_gc=2,is_ref= 0)='new string'

Wenn unset zum Löschen der $b-Variablen verwendet wird, wird refcount_gc von „new string“ um 1 reduziert und wird zu 1

Bei gewöhnlichen Variablen ist das alles normal, aber bei zusammengesetzten Typvariablen (Arrays und Objekten) passiert etwas Interessanteres:

<?php
    $a = array(&#39;meaning&#39; => &#39;life&#39;, &#39;number&#39; => 42);
?>

$a Die internen Speicherinformationen lauten:

a: (refcount=1, is_ref=0)=array (
&#39;meaning&#39; => (refcount=1, is_ref=0)=&#39;life&#39;,
&#39;number&#39; => (refcount=1, is_ref=0)=42
)

Die Array-Variable selbst ($a) In der Engine befindet sich tatsächlich eine Hash-Tabelle. Diese Tabelle enthält zwei Zval-Elemente mit Bedeutung und Nummer, sodass in dieser Codezeile tatsächlich insgesamt 3 Zvals generiert werden. Diese 3 Zvals folgen alle den Referenz- und Zählprinzipien von Variablen. Verwendung Das Diagramm zeigt:

Erklären Sie den PHP-Garbage-Collection-Mechanismus anhand von Beispielen im Detail

Fügen Sie als Nächstes ein Element zu $a hinzu und weisen Sie ihm den Wert eines vorhandenen Elements zu das neue Element:

<?php
    $a = array(&#39;meaning&#39; => &#39;life&#39;, &#39;number&#39; => 42);
    $a[&#39;name&#39;] = $a[&#39;meaning&#39;];
 ?>

Dann ist der interne Speicher von $a, der ref_count von „life“ wird 2 und der ref_count von 42 ist 1:

a: (refcount=1, is_ref=0)=array (
&#39;meaning&#39; => (refcount=2, is_ref=0)=&#39;life&#39;,
&#39;number&#39; => (refcount=1, is_ref=0)=42,
&#39;name&#39; => (refcount=2, is_ref=0)=&#39;life&#39;
)

Wenn Sie die Referenz von zuweisen Wenn Sie das Array zu einem Element im Array hinzufügen, passieren interessante Dinge:

<?php
    $a = array(&#39;one&#39;);
    $a[] = &$a;
?>

Auf diese Weise hat das $a-Array zwei Elemente, eines mit einem Index von 0 und einem Wert des Zeichens eins und das andere mit einem Index von 1, der eine Referenz auf $a selbst ist. Der interne Speicher ist wie folgt:

Erklären Sie den PHP-Garbage-Collection-Mechanismus anhand von Beispielen im Detail

a: (refcount=2, is_ref=1)=array (
0 => (refcount=1, is_ref=0)=&#39;one&#39;,
1 => (refcount=2, is_ref=1)=…
)

array Der ref_count von zval ist 2, was ein Zirkel ist Referenz. Zu diesem Zeitpunkt ist $a nicht gesetzt, dann wird $a aus der Symboltabelle gelöscht und der refcount_gc des zval, auf den $a zeigt, wird um 1 reduziert.

Dann tritt das Problem auf, $a ist Nicht mehr in der Symboltabelle, der Benutzer Auf diese Variable kann nicht mehr zugegriffen werden, aber der refcount_gc des zval, auf den $a zeigt, wird 1 statt 0, sodass er nicht recycelt werden kann, was zu einem Speicherverlust führt Der neue GC soll solchen Müll beseitigen.

Um das Problem zirkulärer Referenzspeicherlecks zu lösen, wird ein synchroner Zyklus-Recycling-Algorithmus verwendet. Wenn der ref_count um 1 reduziert wird und immer noch größer als 0 ist, wird er als verdächtiger Müll betrachtet.

Wenn beispielsweise ein Array oder Objekt zyklisch auf sich selbst verweist und das Array zurücksetzt und refcount-1 immer noch größer als 0 ist, wird es durchlaufen und zum Löschen simuliert. Wenn refcount-1 0 ist, Es wird gelöscht. Wenn es nicht 0 ist, stellen Sie es wieder her.

Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website: PHP-Video-Tutorial

Das obige ist der detaillierte Inhalt vonErklären Sie den PHP-Garbage-Collection-Mechanismus anhand von Beispielen im Detail. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen