Heim  >  Artikel  >  Backend-Entwicklung  >  Erfahren Sie mehr über den Garbage-Collection-Mechanismus von PHP

Erfahren Sie mehr über den Garbage-Collection-Mechanismus von PHP

WBOY
WBOYnach vorne
2022-08-25 11:51:111711Durchsuche

(Empfohlenes Tutorial: PHP-Video-Tutorial)

1. Grundkenntnisse der Referenzzählung

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.

2. Einen ZVAL-Container generieren

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(&#39;a&#39;);
 
//结果
a: (refcount=1, is_ref=0)=&#39;new string&#39;

3 Zählen

Das Zuweisen einer Variablen zu einer anderen Variable erhöht die Anzahl der Referenzen

<?php
$a = "new string";
$b = $a;
xdebug_debug_zval( &#39;a&#39; );
 
//结果
a: (refcount=2, is_ref=0)=&#39;new string&#39;

4. Reduzieren Sie die Anzahl der Referenzen von zval

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( &#39;a&#39; );
unset( $b, $c );
xdebug_debug_zval( &#39;a&#39; );
 
//结果
a: (refcount=3, is_ref=0)=&#39;new string&#39;
a: (refcount=1, is_ref=0)=&#39;new string&#39;

5. Der Zval-Container vom zusammengesetzten Typ

  • unterscheidet sich vom skalaren Typwert
  • Array- und Objekttypvariablen speichern ihre Mitglieder oder Attribute in ihrer eigenen Symboltabelle
  • Dies bedeutet Folgendes: Das Beispiel wird generiert drei Zval-Variablencontainer
  • Die drei Zval-Variablencontainer sind: a, Bedeutung und Zahl

<?php
$a = array( &#39;meaning&#39; => &#39;life&#39;, &#39;number&#39; => 42 );
xdebug_debug_zval( &#39;a&#39; );
 
//结果
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
)

6. Erhöhen Sie die Referenzanzahl des zusammengesetzten Typs

Fügen Sie ein vorhandenes Element zum Array hinzu

<?php
$a = array( &#39;meaning&#39; => &#39;life&#39;, &#39;number&#39; => 42 );
$a[&#39;life&#39;] = $a[&#39;meaning&#39;];
xdebug_debug_zval( &#39;a&#39; );
 
//结果
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;life&#39; => (refcount=2, is_ref=0)=&#39;life&#39;
)

7. Reduzieren Sie die Referenzanzahl zusammengesetzter Typen

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( &#39;meaning&#39; => &#39;life&#39;, &#39;number&#39; => 42 );
$a[&#39;life&#39;] = $a[&#39;meaning&#39;];
unset( $a[&#39;meaning&#39;], $a[&#39;number&#39;] );
xdebug_debug_zval( &#39;a&#39; );
 
//结果
a: (refcount=1, is_ref=0)=array (
   &#39;life&#39; => (refcount=1, is_ref=0)=&#39;life&#39;
)

8. Sonderfälle

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 verarbeiten

Der Synchronisationsalgorithmus wird in PHP 5.3.0 verwendet, um dieses Speicherleckproblem zu lösen

Wenn 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 wird

In 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 werden

Dieser 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

Das andere ist die Verlängerung der Zeit, die der Garbage-Collection-Mechanismus benötigt, um verlorenen Speicher freizugeben

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.

Dieser Vorteil ist besonders deutlich bei lang laufenden Skripten, wie z. B. lang laufenden Testsuiten oder Daemon-Skripten.

(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!

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