(Empfohlenes Tutorial: PHP-Video-Tutorial)
Jede PHP-Variable existiert in einem Variablencontainer namens zval.
Ein zval-Variablencontainer enthält nicht nur den Typ und den Wert der Variablen, sondern auch zwei Bytes zusätzlicher Informationen.
Der erste ist is_ref, ein boolescher Wert, der verwendet wird, um zu identifizieren, ob diese Variable zur Referenzsammlung gehört. Durch dieses Byte kann die PHP-Engine gewöhnliche Variablen von Referenzvariablen unterscheiden. Da PHP Benutzern die Verwendung benutzerdefinierter Referenzen durch die Verwendung von & ermöglicht, gibt es im zval-Variablencontainer auch einen internen Referenzzählmechanismus, um die Speichernutzung zu optimieren.
Das zweite zusätzliche Byte ist Refcount, das die Anzahl der Variablen darstellt, die auf diesen Zval-Variablencontainer verweisen.
Alle Symbole existieren in einer Symboltabelle, in der jedes Symbol einen Gültigkeitsbereich hat und das Hauptskript (z. B. ein über den Browser angefordertes Skript) und jede Funktion oder Methode ebenfalls einen Gültigkeitsbereich haben.
Wenn einer Variablen ein konstanter Wert zugewiesen wird, wird ein ZVAL-Variablencontainer generiert
Wenn Xdebug installiert ist, können Sie diese beiden über xdebug_debug_zval() anzeigen
<?php $a = "new string"; xdebug_debug_zval('a'); //结果 a: (refcount=1, is_ref=0)='new string'
Das Zuweisen einer Variablen zu einer anderen Variable erhöht die Anzahl der Referenzen
<?php $a = "new string"; $b = $a; xdebug_debug_zval( 'a' ); //结果 a: (refcount=2, is_ref=0)='new string'
Verwenden Sie unset(), um die Anzahl der Referenzen zu reduzieren
Der Variablencontainer, der den Typ und den Wert enthält, wird entfernt den Speicher löschen
<?php $a = "new string"; $c = $b = $a; xdebug_debug_zval( 'a' ); unset( $b, $c ); xdebug_debug_zval( 'a' ); //结果 a: (refcount=3, is_ref=0)='new string' a: (refcount=1, is_ref=0)='new string'
<?php $a = array( 'meaning' => 'life', 'number' => 42 ); xdebug_debug_zval( 'a' ); //结果 a: (refcount=1, is_ref=0)=array ( 'meaning' => (refcount=1, is_ref=0)='life', 'number' => (refcount=1, is_ref=0)=42 )
Fügen Sie ein vorhandenes Element zum Array hinzu
<?php $a = array( 'meaning' => 'life', 'number' => 42 ); $a['life'] = $a['meaning']; xdebug_debug_zval( 'a' ); //结果 a: (refcount=1, is_ref=0)=array ( 'meaning' => (refcount=2, is_ref=0)='life', 'number' => (refcount=1, is_ref=0)=42, 'life' => (refcount=2, is_ref=0)='life' )
Das Löschen eines Elements im Array
ähnelt dem Löschen einer Variablen aus dem Bereich
Nach dem Löschen wird der „Refcount des Containers, in dem sich das Element im Array befindet“ angezeigt. Der Wert wird reduziert
<?php $a = array( 'meaning' => 'life', 'number' => 42 ); $a['life'] = $a['meaning']; unset( $a['meaning'], $a['number'] ); xdebug_debug_zval( 'a' ); //结果 a: (refcount=1, is_ref=0)=array ( 'life' => (refcount=1, is_ref=0)='life' )
Wenn wir ein Array selbst als Element dieses Arrays hinzufügen, wird es interessant
Wie oben wird auch beim Aufruf von unset für eine Variable das Symbol und die Variable, auf die es zeigt, gelöscht Die Anzahl der Referenzen im Container wird ebenfalls um 1 reduziert Container), da das Array-Element „1“ immer noch auf das Array selbst verweist, sodass dieser Container nicht gelöscht werden kann.
Da es kein anderes Symbol gibt, das darauf verweist, hat der Benutzer keine Möglichkeit, diese Struktur zu löschen, was zu einem Speicherverlust führt.
Glücklicherweise löscht PHP diese Datenstruktur am Ende der Skriptausführung, aber bevor PHP sie löscht, wird viel Speicher verbraucht. Es ist in Ordnung, wenn die obige Situation nur ein- oder zweimal auftritt, aber wenn Speicherverluste tausende oder sogar hunderttausende Male auftreten, ist dies offensichtlich ein großes Problem. 10 Wie das, was PHP zuvor verwendet hat Die Referenzzählung Der Speichermechanismus kann Speicherlecks mit zirkulären Referenzen nicht verarbeitenDer Synchronisationsalgorithmus wird in PHP 5.3.0 verwendet, um dieses Speicherleckproblem zu lösenWenn sich die Referenzanzahl erhöht, wird sie weiterhin verwendet, und natürlich nicht mehr gebraucht. Im Müll. Wenn der Referenzzähler auf Null reduziert wird, wird der Variablencontainer gelöscht (frei)Das heißt, ein Müllzyklus findet nur dann statt, wenn der Referenzzähler auf einen Wert ungleich Null reduziert wirdIn einem Müll Zyklus, indem Sie die Referenz überprüfen. Überprüfen Sie, ob die Anzahl um 1 dekrementiert wird, und überprüfen Sie, welche variablen Container keine Referenzzeiten haben, um herauszufinden, welcher Teil Müll ist zählt, kann der Müllkreislauf reduziert werdenDieser Algorithmus legt alle möglichen Roots (mögliche Roots sind zval-Variablencontainer) in den Root-Puffer (violett markiert, sogenannter vermuteter Müll), sodass sichergestellt werden kann, dass jeder mögliche Garbage Root gleichzeitig (mögliche Garbage Root) nur einmal erscheint im Puffer. Die Garbage Collection wird nur dann für alle verschiedenen Variablencontainer innerhalb des Puffers durchgeführt, wenn der Root-Puffer voll ist. Sehen Sie sich Schritt A im Bild oben an.
Simulieren Sie in Schritt B das Löschen jeder lila Variablen. Beim Simulieren des Löschens kann der Referenzzähler von gewöhnlichen Variablen, die nicht lila sind, um „1“ reduziert werden. Wenn der Referenzzähler einer gewöhnlichen Variablen 0 wird, simulieren Sie das Löschen der gewöhnlichen Variablen erneut. Jede Variable kann nur einmal simuliert gelöscht werden und wird nach dem simulierten Löschen grau markiert.
In Schritt C stellt die Simulation jede violette Variable wieder her. Die Wiederherstellung ist an Bedingungen geknüpft. Wenn der Referenzzähler der Variablen größer als 0 ist, wird eine simulierte Wiederherstellung durchgeführt. Ebenso kann jede Variable nur einmal wiederhergestellt werden. Nach der Wiederherstellung wird sie als schwarz markiert. Dies ist im Grunde die umgekehrte Operation von Schritt B. Auf diese Weise handelt es sich bei dem verbleibenden Stapel nicht wiederherstellbarer blauer Knoten um die blauen Knoten, die gelöscht werden sollten. Durchlaufen Sie sie in Schritt D und löschen Sie sie 1 Das eine ist die Einsparung von Speicherplatz
13. Fazit des Garbage-Collection-Mechanismus
Der Garbage-Collection-Mechanismus in PHP ist nur wahr im Zyklus-Recycling-Algorithmus Während der Laufzeit erhöht sich der Zeitverbrauch. Bei normalen (kleineren) Skripten sollte es jedoch keinerlei Auswirkungen auf die Leistung geben.
Bei normalen Skripten mit laufenden Recycling-Mechanismen ermöglichen die Speichereinsparungen jedoch die gleichzeitige Ausführung mehrerer solcher Skripte auf Ihrem Server. Weil der insgesamt verwendete Speicher die Obergrenze nicht erreicht hat.
(Empfohlenes Tutorial:
PHP-Video-Tutorial)
Das obige ist der detaillierte Inhalt vonErfahren Sie mehr über den Garbage-Collection-Mechanismus von PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!