Dieser Artikel führt Sie in die Referenzzählung von PHP ein. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.
Mit anderen Worten: Wenn die Anzahl der Referenzen 0 ist, wird diese Variable nicht mehr verwendet und kann über GC recycelt werden, um die belegten Speicherressourcen freizugeben.
Kein Programm kann Speicherressourcen auf unbestimmte Zeit belegen, was oft zu einem ernsthaften Problem führt, nämlich Speicherlecks, die die Zerstörung des Speichers für uns automatisch abschließen. Wie C muss manuell freigegeben werden.
Wie überprüfe ich die Referenzanzahl?
$a = "I am a String"; xdebug_debug_zval('a'); // a: (refcount=1, is_ref=0)='I am a String'
Wie aus dem Obigen ersichtlich ist, ist der Inhalt dieser $a-Variablen Ich bin ein String wie dieser, ein String. Der Refcount in Klammern gibt die Anzahl der Referenzen an und is_ref gibt an, ob auf die Variable verwiesen wird. Sehen wir uns an, wie sich diese beiden Parameter durch die Variablenzuweisung ändern.
$b = $a; xdebug_debug_zval('a'); // a: (refcount=1, is_ref=0)='I am a String' $b = &$a; xdebug_debug_zval('a'); // a: (refcount=2, is_ref=1)='I am a String'
Wenn wir eine normale Zuweisung durchführen, haben refcount und is_ref keine Änderungen, aber wenn wir eine Referenzzuweisung durchführen, können wir sehen, dass refcount 2 und is_ref 1 wird. Dies bedeutet, dass die aktuelle Variable $a durch Referenz zugewiesen wird und ihre Speichersymboltabelle die beiden Variablen $a und $b bedient.
$c = &$a; xdebug_debug_zval('a'); // a: (refcount=3, is_ref=1)='I am a String' unset($c, $b); xdebug_debug_zval('a'); // a: (refcount=1, is_ref=1)='I am a String' $b = &$a; $c = &$a; $b = "I am a String new"; xdebug_debug_zval('a'); // a: (refcount=3, is_ref=1)='I am a String new' unset($a); xdebug_debug_zval('a'); // a: no such symbol
Fügen Sie weiterhin eine Referenzzuweisung zu $c hinzu, und Sie können sehen, dass die Refanzahl weiter zunimmt. Nach dem Deaktivieren von $b und $c kehrt refcount auf 1 zurück. Es ist jedoch zu beachten, dass is_ref immer noch 1 ist. Das heißt, wenn auf diese Variable verwiesen wurde, wird is_ref zu 1, auch wenn die referenzierte Variable Even ist Wenn es nicht gesetzt wurde, bleibt der Wert unverändert.
Schließlich deaktivieren wir $a und die angezeigte Meldung enthält kein solches Symbol. Die aktuelle Variable wurde zerstört und ist keine verwendbare symbolische Referenz mehr. (Beachten Sie, dass Variablen in PHP der Speichersymboltabelle und nicht der tatsächlichen Speicheradresse entsprechen.)
Objektreferenzzählung
// 对象引用计数 class A{ } $objA = new A(); xdebug_debug_zval('objA'); // objA: (refcount=1, is_ref=0)=class A { } $objB = $objA; xdebug_debug_zval('objA'); // objA: (refcount=2, is_ref=0)=class A { } $objC = $objA; xdebug_debug_zval('objA'); // objA: (refcount=3, is_ref=0)=class A { } unset($objB); class C{ } $objC = new C; xdebug_debug_zval('objA'); // objA: (refcount=1, is_ref=0)=class A { }
Hier ist jedoch zu beachten, dass die Symboltabelle des Objekts eine etablierte Verbindung ist. Das heißt, eine erneute Instanziierung oder Änderung von $objC auf NULL hat keinen Einfluss auf den Inhalt von $objA Ist die vorherige Objektzuweisung eine Referenz in PHP? Es wurde bereits im Artikel erklärt. Gewöhnliche Zuweisungsoperationen für Objekte sind ebenfalls Symboltabellenzuweisungen von Referenztypen, sodass wir das &-Symbol nicht hinzufügen müssen.
Referenzzählung von Arrays
// 数组引用计数 $arrA = [ 'a'=>1, 'b'=>2, ]; xdebug_debug_zval('arrA'); // arrA: (refcount=2, is_ref=0)=array ( // 'a' => (refcount=0, is_ref=0)=1, // 'b' => (refcount=0, is_ref=0)=2 // ) $arrB = $arrA; $arrC = $arrA; xdebug_debug_zval('arrA'); // arrA: (refcount=4, is_ref=0)=array ( // 'a' => (refcount=0, is_ref=0)=1, // 'b' => (refcount=0, is_ref=0)=2 // ) unset($arrB); $arrC = ['c'=>3]; xdebug_debug_zval('arrA'); // arrA: (refcount=2, is_ref=0)=array ( // 'a' => (refcount=0, is_ref=0)=1, // 'b' => (refcount=0, is_ref=0)=2 // ) // 添加一个已经存在的元素 $arrA['c'] = &$arrA['a']; xdebug_debug_zval('arrA'); // arrA: (refcount=1, is_ref=0)=array ( // 'a' => (refcount=2, is_ref=1)=1, // 'b' => (refcount=0, is_ref=0)=2, // 'c' => (refcount=2, is_ref=1)=1 // )
Erstens hat jedes Element innerhalb des Arrays seinen eigenen separaten Referenzzähler. Dies ist auch einfacher zu verstehen. Jedes Array-Element kann als separate Variable betrachtet werden, das Array ist jedoch ein Hash-Satz dieser Variablen. Wenn das Objekt Mitgliedsvariablen enthält, tritt der gleiche Effekt auf. Wenn ein Element im Array durch & einer anderen Variablen zugewiesen wird, wird der Refcount dieses Elements erhöht, ohne dass sich dies auf den Refcount des gesamten Arrays auswirkt.
Zweitens beträgt der Standard-Refcount des Arrays 2. Tatsächlich handelt es sich hierbei um eine neue Funktion nach PHP7. Wenn ein Array definiert und initialisiert wird, wird es in ein unveränderliches Array (unveränderliches Array) umgewandelt. Um es von gewöhnlichen Arrays zu unterscheiden, beginnt der Refcount dieses Arrays bei 2. Wenn wir ein Element in diesem Array ändern, ändert sich das Array wieder in ein normales Array, d. h. refcount ändert sich wieder auf 1. Sie können dies selbst ausprobieren. Die offizielle Erklärung dient der Effizienz. Um das spezifische Prinzip zu ermitteln, müssen Sie sich möglicherweise noch mit dem PHP7-Quellcode befassen.
Was Sie bei Speicherlecks beachten sollten
// 对象循环引用 class D{ public $d; } $d = new D; $d->d = $d; xdebug_debug_zval('d'); // d: (refcount=2, is_ref=0)=class D { // public $d = (refcount=2, is_ref=0)=... // } // 数组循环引用 $arrA['arrA'] = &$arrA; xdebug_debug_zval('arrA'); // arrA: (refcount=2, is_ref=1)=array ( // 'a' => (refcount=0, is_ref=0)=1, // 'b' => (refcount=0, is_ref=0)=2, // 'arrA' => (refcount=2, is_ref=1)=... // )
Ob es sich um ein Objekt oder ein Array handelt, wenn beim Drucken und Debuggen Auslassungspunkte wie ... erscheinen, dann gibt es in Ihrem Programm einen Zirkelverweis. Im vorherigen Artikel über das Kopieren von Objekten in PHP haben wir auch über dieses Zirkelverweisproblem gesprochen, daher sollten wir diesem Problem bei der täglichen Entwicklung immer Aufmerksamkeit schenken.
Empfohlenes Lernen:
Das obige ist der detaillierte Inhalt vonWas bedeutet Referenzzählung in PHP?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!