Heim Backend-Entwicklung PHP-Tutorial Eine kurze Diskussion des PHP-Quellcodes 34: Der neu hinzugefügte Garbage-Collection-Mechanismus von PHP5.3 (Garbage Collection)

Eine kurze Diskussion des PHP-Quellcodes 34: Der neu hinzugefügte Garbage-Collection-Mechanismus von PHP5.3 (Garbage Collection)

Jun 29, 2018 am 10:07 AM

Dieser Artikel stellt hauptsächlich den PHP-Quellcode 34 vor: den neu hinzugefügten Garbage Collection-Mechanismus (Garbage Collection), der einen gewissen Referenzwert hat. Jetzt kann ich ihn mit Ihnen teilen .

Eine kurze Diskussion des PHP-Quellcodes 34: Der neue Garbage-Collection-Mechanismus (Garbage Collection)
Im vorherigen Artikel eine kurze Diskussion des PHP-Quellcodes 33: PHP5.3 Neue Ergänzungen Die Grundlagen der Garbage Collection führen in einige Grundkenntnisse des Garbage Collection-Mechanismus ein. Heute schauen wir uns die Initialisierung an und erweitern den Garbage-Puffer- und Garbage-Collection-Prozess.
Für die offizielle Dokumentation klicken Sie bitte auf Garbage Collection
Adresse der chinesischen Version: http://docs.php.net/manual/zh/features.gc.php
[Initialisierung]
In zend/ zend_gc .c Zeile 121 hat die Funktion gc_init, die die Initialisierung von gc implementiert. Der Code lautet wie folgt:

 ZEND_API void gc_init(TSRMLS_D){
if (GC_G(buf) == NULL && GC_G(gc_enabled)) {
GC_G(buf) = (gc_root_buffer*) malloc(sizeof(gc_root_buffer) * GC_ROOT_BUFFER_MAX_ENTRIES);
GC_G(last_unused) = &GC_G(buf)[GC_ROOT_BUFFER_MAX_ENTRIES];
gc_reset(TSRMLS_C);
}}
Nach dem Login kopieren

Zeile 123 bestimmt, ob es leer ist und ob gc aktiviert ist. Wenn beide wahr sind, gehe zu Zeile 124
Zeile 124 ruft malloc direkt auf, um 10.000 gc_root_buffer-Speicher zuzuweisen.
Zeile 125 setzt die globale Variable last_unused auf das Ende des GC-Puffers.
Zeile 126 setzt den gesamten Garbage-Collection-Mechanismus zurück. Der Code beginnt in Zeile 88 von zend/zend_gc.c wie folgt:

ZEND_API void gc_reset(TSRMLS_D){
GC_G(gc_runs) = 0;
GC_G(collected) = 0; #if GC_BENCH
GC_G(root_buf_length) = 0;
GC_G(root_buf_peak) = 0;
GC_G(zval_possible_root) = 0;
GC_G(zobj_possible_root) = 0;
GC_G(zval_buffered) = 0;
GC_G(zobj_buffered) = 0;
GC_G(zval_remove_from_buffer) = 0;
GC_G(zobj_remove_from_buffer) = 0;
GC_G(zval_marked_grey) = 0;
GC_G(zobj_marked_grey) = 0;#endif 
GC_G(roots).next = &GC_G(roots);
GC_G(roots).prev = &GC_G(roots); if (GC_G(buf)) {
GC_G(unused) = NULL;
GC_G(first_unused) = GC_G(buf); 
GC_G(zval_to_free) = NULL;
} else {
GC_G(unused) = NULL;
GC_G(first_unused) = NULL;
GC_G(last_unused) = NULL;
}}
Nach dem Login kopieren

Die Zeilen 90–91 legen die Statistik der Anzahl der GC-Läufe fest (gc_runs ) und gc Die Anzahl des Mülls (gesammelt) beträgt 0.
Die Zeilen 106–107 legen den vorherigen Knoten und den nächsten Knoten des Kopfknotens der doppelt verknüpften Liste so fest, dass sie auf sich selbst zeigen.

Was gc_enabled betrifft, ist es standardmäßig aktiviert und kann in php.ini konfiguriert werden.
Der Implementierungscode lautet wie folgt in Zeile 93 von zend/zend.c:

STD_ZEND_INI_BOOLEAN("zend.enable_gc","1",ZEND_INI_ALL,OnUpdateGCEnabled,   gc_enabled, zend_gc_globals,        gc_globals)
Nach dem Login kopieren

Der Initialisierungsaufruf befindet sich in Zeile 79 von zend/zend.c

 static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */{
OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); if (GC_G(gc_enabled)) {
gc_init(TSRMLS_C);
} return SUCCESS;}
Nach dem Login kopieren

[Zum Müll hinzufügen buffer]
Verfolgen Sie den PHP-Quellcode zend/zend_execute_API.c Zeile 424
[_zval_ptr_dtor] -> [GC_ZVAL_CHECK_POSSIBLE_ROOT()] -> [gc_zval_possible_root()]
wo Führen Sie in der Funktion gc_zval_check _possible_root() nur Garbage Collection-Vorgänge für Arrays und Objekte aus

Der Code der Funktion gc_zval_possible_root lautet wie folgt:

ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC){
if (UNEXPECTED(GC_G(free_list) != NULL &&
               GC_ZVAL_ADDRESS(zv) != NULL &&
           GC_ZVAL_GET_COLOR(zv) == GC_BLACK) &&
           (GC_ZVAL_ADDRESS(zv) < GC_G(buf) ||
            GC_ZVAL_ADDRESS(zv) >= GC_G(last_unused))) {
/* The given zval is a garbage that is going to be deleted by
 * currently running GC */
return;
} if (zv->type == IS_OBJECT) {
GC_ZOBJ_CHECK_POSSIBLE_ROOT(zv);
return;
} 
GC_BENCH_INC(zval_possible_root); if (GC_ZVAL_GET_COLOR(zv) != GC_PURPLE) {
GC_ZVAL_SET_PURPLE(zv); if (!GC_ZVAL_ADDRESS(zv)) {
gc_root_buffer *newRoot = GC_G(unused); if (newRoot) {
GC_G(unused) = newRoot->prev;
} else if (GC_G(first_unused) != GC_G(last_unused)) {
newRoot = GC_G(first_unused);
GC_G(first_unused)++;
} else {
if (!GC_G(gc_enabled)) {
GC_ZVAL_SET_BLACK(zv);
return;
}
zv->refcount__gc++;
gc_collect_cycles(TSRMLS_C);
zv->refcount__gc--;
newRoot = GC_G(unused);
if (!newRoot) {
return;
}
GC_ZVAL_SET_PURPLE(zv);
GC_G(unused) = newRoot->prev;
} 
newRoot->next = GC_G(roots).next;
newRoot->prev = &GC_G(roots);
GC_G(roots).next->prev = newRoot;
GC_G(roots).next = newRoot; 
GC_ZVAL_SET_ADDRESS(zv, newRoot); 
newRoot->handle = 0;
newRoot->u.pz = zv; 
GC_BENCH_INC(zval_buffered);
GC_BENCH_INC(root_buf_length);
GC_BENCH_PEAK(root_buf_peak, root_buf_length);
}
}}
Nach dem Login kopieren

Zeilen 132–140 prüfen, ob die zval-Knoteninformationen vorhanden sind wurde in den Knotenpuffer gestellt. Wenn es in den Knotenpuffer gestellt wurde, kehre direkt zurück, was seine Leistung optimieren kann

Die Zeilen 142 bis 145 verarbeiten den Objektknoten und kehren direkt zurück, ohne nachfolgende Vorgänge auszuführen

Zeile 149 bestimmt, ob der Knoten lila markiert wurde. Wenn er lila ist, wird er nicht mehr zum Knotenpuffer hinzugefügt. Dadurch wird sichergestellt, dass ein Knoten nur einmal zum Puffer hinzugefügt wird.

Zeile 150 markiert die Farbe des Knotens als lila, was darauf hinweist, dass der Knoten zum Puffer hinzugefügt wurde und beim nächsten Mal nicht hinzugefügt werden muss.

Zeilen 153 bis 157 finden den neuer Knoten Wenn der Puffer voll ist, wird ein Garbage-Collection-Vorgang durchgeführt.

Die Zeilen 176–184 fügen neue Knoten zur doppelt verknüpften Liste hinzu, in der sich der Puffer befindet.

[Garbage-Collect-Prozess]
Wenn in der Funktion gc_zval_possible_root der Puffer voll ist, ruft das Programm die Funktion gc_collect_cycles auf, um Garbage-Collection-Vorgänge durchzuführen. Ab Zeile 615 der Datei zend/zend_gc.c lautet der Implementierungscode wie folgt:

 ZEND_API int gc_collect_cycles(TSRMLS_D){
int count = 0; if (GC_G(roots).next != &GC_G(roots)) {
zval_gc_info *p, *q, *orig_free_list, *orig_next_to_free; if (GC_G(gc_active)) {
return 0;
}
GC_G(gc_runs)++;
GC_G(zval_to_free) = FREE_LIST_END;
GC_G(gc_active) = 1;
gc_mark_roots(TSRMLS_C);
gc_scan_roots(TSRMLS_C);
gc_collect_roots(TSRMLS_C); 
orig_free_list = GC_G(free_list);
orig_next_to_free = GC_G(next_to_free);
p = GC_G(free_list) = GC_G(zval_to_free);
GC_G(zval_to_free) = NULL;
GC_G(gc_active) = 0; /* First call destructors */
while (p != FREE_LIST_END) {
if (Z_TYPE(p->z) == IS_OBJECT) {
if (EG(objects_store).object_buckets &&
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].valid &&
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount <= 0 &&
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.dtor &&
!EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].destructor_called) { 
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].destructor_called = 1;
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount++;
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.dtor(EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.object, Z_OBJ_HANDLE(p->z) TSRMLS_CC);
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount--;
}
}
count++;
p = p->u.next;
} /* Destroy zvals */
p = GC_G(free_list);
while (p != FREE_LIST_END) {
GC_G(next_to_free) = p->u.next;
if (Z_TYPE(p->z) == IS_OBJECT) {
if (EG(objects_store).object_buckets &&
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].valid &&
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount <= 0) {
EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount = 1;
Z_TYPE(p->z) = IS_NULL;
zend_objects_store_del_ref_by_handle_ex(Z_OBJ_HANDLE(p->z), Z_OBJ_HT(p->z) TSRMLS_CC);
}
} else if (Z_TYPE(p->z) == IS_ARRAY) {
Z_TYPE(p->z) = IS_NULL;
zend_hash_destroy(Z_ARRVAL(p->z));
FREE_HASHTABLE(Z_ARRVAL(p->z));
} else {
zval_dtor(&p->z);
Z_TYPE(p->z) = IS_NULL;
}
p = GC_G(next_to_free);
} /* Free zvals */
p = GC_G(free_list);
while (p != FREE_LIST_END) {
q = p->u.next;
FREE_ZVAL_EX(&p->z);
p = q;
}
GC_G(collected) += count;
GC_G(free_list) = orig_free_list;
GC_G(next_to_free) = orig_next_to_free;
} return count;}
Nach dem Login kopieren

Zeile 619 bestimmt, ob der Puffer leer ist, wird keine Speicherbereinigung durchgeführt
Zeile 622 bestimmt, ob der Garbage-Collection-Vorgang regelmäßig ausgeführt wird. Wenn er gerade ausgeführt wird, kehren Sie direkt zurück
Zeilen 625 bis 627, um die Anzahl der Garbage-Collection-Vorgänge um 1 zu erhöhen, die freie Liste zu initialisieren und gc_active auf 1 zu setzen Geben Sie an, dass die Müllrückgabe im Gange ist
Zeile 628 hier Als Schritt B des Algorithmus in seinem offiziellen Dokument verwendet der Algorithmus die Tiefensuche, um alle möglichen Wurzeln zu finden. Nachdem er sie gefunden hat, wird der Referenzzähler in jedem Variablencontainer dekrementiert um 1", um sicherzustellen, dass derselbe Variablencontainer nicht zweimal dekrementiert wird. ″, grau markiert, das um 1 reduziert wurde.
Zeile 629 Dies ist Schritt C des Algorithmus. Der Algorithmus verwendet erneut eine Tiefensuche nach Jeder Wurzelknoten und überprüft den Referenzzähler jedes Variablencontainers. Wenn der Referenzzähler 0 ist, wird der Variablencontainer weiß markiert. Wenn die Anzahl der Referenzen größer als 0 ist, wird der Referenzzähler mithilfe der Tiefe um 1 verringert. An diesem Punkt wird die erste Suche fortgesetzt (dh der Referenzzähler wird um 1 erhöht) und dann erneut mit Schwarz markiert 🎜>Im letzten Schritt D des Algorithmus in Zeile 630 durchläuft der Algorithmus den Root-Puffer, um ihn zu entfernen von dort aus die Variablencontainer-Wurzeln (zval-Wurzeln) und prüft gleichzeitig, ob Variablencontainer vorhanden sind, die im vorherigen Schritt weiß markiert wurden. Die Variablencontainer werden gelöscht ;gc_collect_roots() -> zval_collect_white() ] Wir können sehen, dass die weiß markierten Knoten zur Liste der globalen Variablen zval_to_free hinzugefügt werden. Die Zeilen 632–633 speichern die globalen Variablen free_list und next_to_free in den entsprechenden temporären Variablen und werden am Ende in ihrem aktuellen Zustand wiederhergestellt. Die Zeilen 634 bis 635 werden initialisiert, die zu löschende Zval-Liste und der Garbage Collection-Vorgang Status ist inaktiv.
Zeilen 639–655 rufen den Destruktor zum ersten Mal auf und zählen die Anzahl der gelöschten Variablen
Zeilen 639–678 löschen Variablen
Zeilen 682–686 geben Speicher frei
Die Zeilen 687 bis 689 verarbeiten die Garbage-Count-Statistiken und stellen die Variablen free_list und next_to_free wieder her.

Das Obige ist der gesamte Inhalt dieses Artikels, der für Sie hilfreich sein wird Bitte beachten Sie die chinesische PHP-Website

Verwandte Empfehlungen:

Eine kurze Diskussion des PHP-Quellcodes 33: Die Grundlagen des neuen Garbage Collection-Mechanismus (Garbage Collection) in PHP5.3

Eine kurze Beschreibung Diskussion des PHP-Quellcodes 32: Emalloc/Efree-Schicht und Heap-Schicht im PHP-Speicherpool

Eine kurze Diskussion des PHP-Quellcodes 29: Über die Vererbung von Schnittstellen

Das obige ist der detaillierte Inhalt vonEine kurze Diskussion des PHP-Quellcodes 34: Der neu hinzugefügte Garbage-Collection-Mechanismus von PHP5.3 (Garbage Collection). 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 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 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)

Curl in PHP: So verwenden Sie die PHP -Curl -Erweiterung in REST -APIs Curl in PHP: So verwenden Sie die PHP -Curl -Erweiterung in REST -APIs Mar 14, 2025 am 11:42 AM

Die PHP Client -URL -Erweiterung (CURL) ist ein leistungsstarkes Tool für Entwickler, das eine nahtlose Interaktion mit Remote -Servern und REST -APIs ermöglicht. Durch die Nutzung von Libcurl, einer angesehenen Bibliothek mit Multi-Protokoll-Dateien, erleichtert PHP Curl effiziente Execu

12 Beste PHP -Chat -Skripte auf Codecanyon 12 Beste PHP -Chat -Skripte auf Codecanyon Mar 13, 2025 pm 12:08 PM

Möchten Sie den dringlichsten Problemen Ihrer Kunden in Echtzeit und Sofortlösungen anbieten? Mit Live-Chat können Sie Echtzeitgespräche mit Kunden führen und ihre Probleme sofort lösen. Sie ermöglichen es Ihnen, Ihrem Brauch einen schnelleren Service zu bieten

Erklären Sie das Konzept der späten statischen Bindung in PHP. Erklären Sie das Konzept der späten statischen Bindung in PHP. Mar 21, 2025 pm 01:33 PM

In Artikel wird die in PHP 5.3 eingeführte LSB -Bindung (LSB) erörtert, die die Laufzeitauflösung der statischen Methode ermöglicht, um eine flexiblere Vererbung zu erfordern. Die praktischen Anwendungen und potenziellen Perfo von LSB

Erklären Sie JSON Web Tokens (JWT) und ihren Anwendungsfall in PHP -APIs. Erklären Sie JSON Web Tokens (JWT) und ihren Anwendungsfall in PHP -APIs. Apr 05, 2025 am 12:04 AM

JWT ist ein offener Standard, der auf JSON basiert und zur sicheren Übertragung von Informationen zwischen Parteien verwendet wird, hauptsächlich für die Identitätsauthentifizierung und den Informationsaustausch. 1. JWT besteht aus drei Teilen: Header, Nutzlast und Signatur. 2. Das Arbeitsprinzip von JWT enthält drei Schritte: Generierung von JWT, Überprüfung von JWT und Parsingnayload. 3. Bei Verwendung von JWT zur Authentifizierung in PHP kann JWT generiert und überprüft werden, und die Funktionen und Berechtigungsinformationen der Benutzer können in die erweiterte Verwendung aufgenommen werden. 4. Häufige Fehler sind Signaturüberprüfungsfehler, Token -Ablauf und übergroße Nutzlast. Zu Debugging -Fähigkeiten gehört die Verwendung von Debugging -Tools und Protokollierung. 5. Leistungsoptimierung und Best Practices umfassen die Verwendung geeigneter Signaturalgorithmen, das Einstellen von Gültigkeitsperioden angemessen.

Rahmensicherheitsmerkmale: Schutz vor Schwachstellen. Rahmensicherheitsmerkmale: Schutz vor Schwachstellen. Mar 28, 2025 pm 05:11 PM

In Artikel werden wichtige Sicherheitsfunktionen in Frameworks erörtert, um vor Schwachstellen zu schützen, einschließlich Eingabevalidierung, Authentifizierung und regelmäßigen Aktualisierungen.

Anpassung/Erweiterung von Frameworks: So fügen Sie benutzerdefinierte Funktionen hinzu. Anpassung/Erweiterung von Frameworks: So fügen Sie benutzerdefinierte Funktionen hinzu. Mar 28, 2025 pm 05:12 PM

In dem Artikel werden Frameworks hinzugefügt, das sich auf das Verständnis der Architektur, das Identifizieren von Erweiterungspunkten und Best Practices für die Integration und Debuggierung hinzufügen.

Wie sende ich eine Postanforderung mit JSON -Daten mithilfe der Curl -Bibliothek von PHP? Wie sende ich eine Postanforderung mit JSON -Daten mithilfe der Curl -Bibliothek von PHP? Apr 01, 2025 pm 03:12 PM

Senden von JSON -Daten mithilfe der Curl -Bibliothek von PHP in der PHP -Entwicklung müssen häufig mit externen APIs interagieren. Eine der gängigen Möglichkeiten besteht darin, die Curl Library zu verwenden, um Post � ...

See all articles