Inhaltsverzeichnis
Die Struktur von zval
Speicherlecks durch Zirkelverweise
Der Recyclingprozess von Objekten und Arrays. Die Garbage Collection von PHP7 besteht aus zwei Teilen, einem ist der Garbage Collector und einem ist der Garbage-Collection-Algorithmus.
Wenn Ihre Variable kein Müll ist, werden die gesamten Variablenreferenzen definitiv nicht 0 sein, nachdem die Referenzen aller ihrer Mitgliedsvariablen um eins reduziert wurden.
Es ist ziemlich schwer zu erklären, also geben wir ein Beispiel. Als ich sf.gg zum ersten Mal durchsuchte, sah ich eine Frage zu GC und beantwortete sie. In Bezug auf den GC-Garbage-Collection-Mechanismus lautet das Thema wie folgt:
Heim Backend-Entwicklung PHP7 So implementieren Sie den Garbage-Collection-Mechanismus in PHP7

So implementieren Sie den Garbage-Collection-Mechanismus in PHP7

May 24, 2021 am 09:21 AM
php7 垃圾回收机制

In diesem Artikel erfahren Sie, wie Sie den Garbage-Collection-Mechanismus in PHP7 implementieren. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.

So implementieren Sie den Garbage-Collection-Mechanismus in PHP7

Wenn ich unseren PHP-GC verstehe, halte ich es für notwendig, die zugrunde liegende Implementierung unserer PHP-Variablen vorzustellen.

Die Struktur von zval

// php 变量对于的c结构体
struct _zval_struct {
    zend_value value;
    union {
       ……
    } u1;
    union {
        ……
    } u2;
};
Nach dem Login kopieren

Da es hauptsächlich um die Speicherbereinigung geht, finden Sie hier eine kurze Einführung in die Funktionen der u1 u2-Union
u1 Die Struktur ist relativ komplex, ich denke, sie wird hauptsächlich zur Identifizierung von Variablentypen verwendet
u2 Die meisten davon sind Hilfsfelder, die Implementierung interner Funktionen von Variablen, die Verbesserung der Cache-Freundlichkeit usw.
Als nächstes kommt unser Protagonist

zend_value Es ist auch eine in die Struktur eingebettete Union

typedef union _zend_value {
    zend_long         lval;//整形
    double            dval;//浮点型
    zend_refcounted  *counted;//获取不同类型的gc头部
    zend_string      *str;//string字符串
    zend_array       *arr;//数组
    zend_object      *obj;//对象
    zend_resource    *res;//资源
    zend_reference   *ref;//是否是引用类型
  
    // 忽略下面的结构,与我们讨论无关
    zend_ast_ref     *ast;
    zval             *zv;
    void             *ptr;
    zend_class_entry *ce;
    zend_function    *func;
    struct {
        ZEND_ENDIAN_LOHI(
            uint32_t w1,
            uint32_t w2)
    } ww;
} zend_value;
Nach dem Login kopieren

Der Referenzzähler zend_refcounted *counted wird in aufgezeichnet der Wert von zval Dieser Typ basiert auch auf unserem Garbage-Collection-Mechanismus.

typedef struct _zend_refcounted_h {
    uint32_t         refcount;          /* reference counter 32-bit */
    union {
        struct {
            ZEND_ENDIAN_LOHI_3(
                zend_uchar    type,
                zend_uchar    flags,    /* used for strings & objects */
                uint16_t      gc_info)  /* keeps GC root number (or 0) and color */
        } v;
        uint32_t type_info;
    } u;
} zend_refcounted_h;
Nach dem Login kopieren

Alle komplexen Typdefinitionen beginnen mit der Struktur zend_refcounted_h. Diese Struktur verfügt daher auch über GC-bezogene Strukturen. Daher muss sich der GC beim GC-Recycling nicht um den jeweiligen Typ kümmern können als zend_refcounted*-Strukturen verarbeitet werden.
#Automatisches Recycling von Variablen

Mit Ausnahme von Array- und Objekttypvariablen in PHP werden die meisten anderen automatisch recycelt
PHP Das Recycling gewöhnlicher Variablen hängt von der Anzahl der Verweise auf die Variable ab .

Offizielles Beispiel

$a = 1;
$b = $a;
xdebug_debug_zval('a');
$a =10;
xdebug_debug_zval('a');
unset($a);
xdebug_debug_zval('a');
Nach dem Login kopieren

Das Ergebnis

a:
(refcount=2, is_ref=0),int 1
a:
(refcount=1, is_ref=0),int 10
a: no such symbol
Nach dem Login kopieren

Sie können sehen, dass, wenn $a = 10 den COW-Mechanismus (Copy-on-Write) von PHP beinhaltet, $b das ursprüngliche $a kopiert und diese beseitigt. Die Referenzbeziehung zwischen a, sodass die Anzahl der Referenzen (Refcount) von a auf 1 reduziert wird.

Nachdem wir t($a) verwendet haben, wird die Anzahl der Verweise auf a zu 0. Dies wird als Müllvariable betrachtet und gibt Speicherplatz frei.

Ein weiteres Beispiel

$a = [1];
$a[1] = &$a;
unset($a);
Nach dem Login kopieren

Vor unset($a) ist der Typ von $a ein Referenztyp

a:
(refcount=2, is_ref=1),
array (size=2)
  0 => (refcount=1, is_ref=0),int 1
  1 => (refcount=2, is_ref=1),
    &array<
Nach dem Login kopieren

unset($a) Danach sieht es so aus

Zu diesem Zeitpunkt wir unset Während des Betriebs ändert sich refcount von 2 auf 1. Da es eine interne Referenz gibt, die auf $a zeigt, wird der von ihr belegte Speicherplatz nicht extern zerstört.

Dann ist unser Außenbezug kaputt und wir können ihn nicht nutzen. Es wird zu einem „Waise“, was in der C-Sprache als Wild-Zeiger bezeichnet wird. In PHP nennt man das einen Zirkelverweis. Speicherleck. Wenn Sie die Variable zerstören möchten, können Sie nur warten, bis das PHP-Skript beendet ist.

Speicherlecks durch Zirkelverweise

Um diesen Müll zu beseitigen, werden zwei Richtlinien eingeführt

  • Wenn der Referenzzähler auf Null reduziert wird, wird der Variablencontainer gelöscht (frei), was kein Müll ist

  • Wenn der Referenzzähler von zval reduziert wird und immer noch größer als 0 ist, gelangt er in den Müllkreislauf. Zweitens können Sie während eines Garbage-Zyklus herausfinden, welche Teile Garbage sind, indem Sie prüfen, ob die Referenzanzahl um 1 reduziert wird und welche Variablencontainer keine Referenzen haben.

Zirkuläre Referenzen erscheinen grundsätzlich nur in Arrays und Objekten. Das Objekt ist, weil es selbst eine Referenz ist.

Der Recyclingprozess von Objekten und Arrays. Die Garbage Collection von PHP7 besteht aus zwei Teilen, einem ist der Garbage Collector und einem ist der Garbage-Collection-Algorithmus.

Der Garbage Collector sammelt die gerade erwähnten Elemente, die möglicherweise Müll sind, im Recyclingpool, dh er legt die Variablen mit zend_refcount>0 im Recyclingpool ab. Wenn der Wert des Recyclingpools einen bestimmten Betrag erreicht, wird er gleichmäßig durchlaufen. Führen Sie eine simulierte Löschung durch. Wenn zend_refcount=0 ist, wird es als Müll betrachtet und direkt gelöscht.

Durchlaufen Sie jede Variable im Recycling-Pool und dann jedes Mitglied basierend auf jeder Variablen. Wenn die Mitglieder noch verschachtelt sind, fahren Sie mit dem Durchlaufen fort. Setzen Sie dann den simulierten Refcount aller Mitglieder auf -1. Wenn der Referenzzähler der externen Variablen zu diesem Zeitpunkt 0 ist. Dann kann es eindeutig als Müll betrachtet werden. Wenn er größer als 0 ist, wird die Anzahl der Referenzen wiederhergestellt und aus dem Garbage Collection-Pool entfernt.

Das Prinzip der Garbage Collection

Wenn Ihre Variable kein Müll ist, werden die gesamten Variablenreferenzen definitiv nicht 0 sein, nachdem die Referenzen aller ihrer Mitgliedsvariablen um eins reduziert wurden.

Beispiel

Es ist ziemlich schwer zu erklären, also geben wir ein Beispiel. Als ich sf.gg zum ersten Mal durchsuchte, sah ich eine Frage zu GC und beantwortete sie. In Bezug auf den GC-Garbage-Collection-Mechanismus lautet das Thema wie folgt:

//我的回答
1、只要zval.value的refcount减一,然后缺其refcount的值不为0那么它就可能是垃圾,进入垃圾周期。
2、进入垃圾池遍历所有成员,包括其嵌套的成员,都对其做 refcount-1的操作,看外部的引用是否为0。

那么对于 题主的问题来说,
首先,你要想$a为垃圾,一定要先对 unset($a)操作,那么此时 $a的 refcount = 2
对于$a[0] refcount-1 不影响外部的$a,
$a[1] refcount-1 ,此时 $a的 refount=1
$a[2] refcount-1 ,此时 $a 的 refount=0 
模拟减结束,那么此变量被当成垃圾回收。
Nach dem Login kopieren

Empfohlenes Lernen:
php-Video-TutorialSo implementieren Sie den Garbage-Collection-Mechanismus in PHP7

Das obige ist der detaillierte Inhalt vonSo implementieren Sie den Garbage-Collection-Mechanismus in PHP7. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So lösen Sie das Problem, wenn PHP7 erkennt, dass der TCP-Port nicht funktioniert So lösen Sie das Problem, wenn PHP7 erkennt, dass der TCP-Port nicht funktioniert Mar 22, 2023 am 09:30 AM

In PHP5 können wir die Funktion fsockopen() verwenden, um den TCP-Port zu erkennen. Mit dieser Funktion können Sie eine Netzwerkverbindung herstellen und eine Netzwerkkommunikation durchführen. In PHP7 kann die Funktion fsockopen() jedoch auf einige Probleme stoßen, z. B. dass der Port nicht geöffnet werden kann, keine Verbindung zum Server hergestellt werden kann usw. Um dieses Problem zu lösen, können wir die Funktionen socket_create() und socket_connect() verwenden, um den TCP-Port zu erkennen.

Was soll ich tun, wenn das Plug-in in php7.0 installiert ist, aber immer noch angezeigt wird, dass es nicht installiert ist? Was soll ich tun, wenn das Plug-in in php7.0 installiert ist, aber immer noch angezeigt wird, dass es nicht installiert ist? Apr 02, 2024 pm 07:39 PM

So beheben Sie das Problem, dass das Plugin in PHP 7.0 nicht installiert ist: Überprüfen Sie die Plugin-Konfiguration und aktivieren Sie das Plugin. Starten Sie PHP neu, um die Konfigurationsänderungen zu übernehmen. Überprüfen Sie die Berechtigungen der Plugin-Datei, um sicherzustellen, dass sie korrekt sind. Installieren Sie fehlende Abhängigkeiten, um sicherzustellen, dass das Plugin ordnungsgemäß funktioniert. Wenn alle anderen Schritte fehlschlagen, erstellen Sie PHP neu. Weitere mögliche Ursachen sind inkompatible Plugin-Versionen, das Laden der falschen Version oder PHP-Konfigurationsprobleme.

So installieren Sie die Mongo-Erweiterung in PHP7.0 So installieren Sie die Mongo-Erweiterung in PHP7.0 Nov 21, 2022 am 10:25 AM

So installieren Sie die Mongo-Erweiterung in PHP7.0: 1. Erstellen Sie die Mongodb-Benutzergruppe und den Mongodb-Benutzer. 2. Laden Sie das Mongodb-Quellcodepaket herunter und platzieren Sie das Quellcodepaket im Verzeichnis „/usr/local/src/“. Geben Sie das Verzeichnis „src/“ ein. 4. Entpacken Sie das Quellcodepaket. 6. Kopieren Sie die Dateien in das Verzeichnis „mongodb/“.

Ein Artikel über den Garbage-Collection-Mechanismus in PHP Ein Artikel über den Garbage-Collection-Mechanismus in PHP Aug 26, 2022 am 10:48 AM

Dieser Artikel wird Ihnen ein tiefgreifendes Verständnis des Garbage-Collection-Mechanismus in PHP vermitteln. Ich hoffe, er wird Ihnen hilfreich sein!

So installieren und implementieren Sie PHP7.0 So installieren und implementieren Sie PHP7.0 Nov 30, 2022 am 09:56 AM

So installieren und implementieren Sie PHP7.0: 1. Gehen Sie zur offiziellen PHP-Website, um die dem lokalen System entsprechende Installationsversion herunterzuladen. 2. Extrahieren Sie die heruntergeladene ZIP-Datei in das angegebene Verzeichnis. 3. Öffnen Sie das Befehlszeilenfenster und gehen Sie zu das Verzeichnis „E:\php7“ Führen Sie einfach den Befehl „php -v“ aus.

FAQ-Leitfaden zur PHP-Serverumgebung: Häufige Probleme schnell lösen FAQ-Leitfaden zur PHP-Serverumgebung: Häufige Probleme schnell lösen Apr 09, 2024 pm 01:33 PM

Zu den gängigen Lösungen für PHP-Serverumgebungen gehört die Sicherstellung, dass die richtige PHP-Version installiert ist und relevante Dateien in das Modulverzeichnis kopiert wurden. Deaktivieren Sie SELinux vorübergehend oder dauerhaft. Überprüfen und konfigurieren Sie PHP.ini, um sicherzustellen, dass die erforderlichen Erweiterungen hinzugefügt und korrekt eingerichtet wurden. Starten oder starten Sie den PHP-FPM-Dienst neu. Überprüfen Sie die DNS-Einstellungen auf Auflösungsprobleme.

Entschlüsselung des Speicherverwaltungs- und Garbage-Collection-Mechanismus der Go-Sprache Entschlüsselung des Speicherverwaltungs- und Garbage-Collection-Mechanismus der Go-Sprache Nov 30, 2023 am 09:17 AM

Die Go-Sprache ist eine effiziente, sichere und gleichzeitige Programmiersprache. Das Design des Speicherverwaltungs- und Garbage-Collection-Mechanismus ist ebenfalls ein einzigartiges Merkmal. In diesem Artikel werden die Speicherverwaltungs- und Speicherbereinigungsmechanismen der Go-Sprache ausführlich entschlüsselt. 1. Speicherverwaltung In der Go-Sprache umfasst die Speicherverwaltung zwei Aspekte: Speicherzuweisung und Speicherfreigabe. 1.1 Speicherzuweisung In der Go-Sprache weisen wir Speicher über die integrierten Funktionen new und make zu. Unter anderem gibt new einen Zeiger auf den neu zugewiesenen Nullwert zurück, während make einen angegebenen Typ und seine Länge zurückgibt.

Was ist besser, PHP8 oder PHP7? Was ist besser, PHP8 oder PHP7? Nov 16, 2023 pm 03:09 PM

Im Vergleich zu PHP7 bietet PHP8 einige Vorteile und Verbesserungen in Bezug auf Leistung, neue Funktionen und Syntaxverbesserungen, Typsystem, Fehlerbehandlung und Erweiterungen. Die Wahl der zu verwendenden Version hängt jedoch von Ihren spezifischen Anforderungen und Projektumständen ab. Detaillierte Einführung: 1. Leistungsverbesserung: PHP8 führt den Just-in-Time-Compiler (JIT) ein, der die Ausführungsgeschwindigkeit des Codes verbessern kann. 2. Neue Funktionen und Syntaxverbesserungen. PHP8 unterstützt die Deklaration benannter Parameter und optionaler Parameter. Durch die flexiblere Gestaltung von Funktionen werden anonyme Klassen, Typdeklarationen von Eigenschaften usw. eingeführt.

See all articles