In diesem Artikel werden hauptsächlich die Grundlagen des PHP-Quellcodes 33 vorgestellt: Der neu hinzugefügte Garbage Collection-Mechanismus (Garbage Collection) hat einen gewissen Referenzwert dazu.
Lassen Sie uns kurz über PHP-Quellcode 33 sprechen: Die Grundlagen des neuen Garbage-Collection-Mechanismus (Garbage Collection) in PHP5.3
PHP5.3 verfügt über einen neuen Garbage-Collection-Mechanismus, was als sehr fortgeschritten gilt, hat mich dazu verführt, die fortgeschrittene Implementierung zu sehen.
Für die offizielle Dokumentation klicken Sie bitte auf Garbage Collection
Adresse der chinesischen Version: http://docs.php.net/manual/zh/features.gc.php
[Einbettungsmethode des Garbage Collection-Mechanismus]
Auf die Datei zend_gc.h wird in Zeile 749 von zend.h verwiesen: #include "zend_gc.h"
Dadurch werden ALLOC_ZVAL und andere Makros in der Datei zend_alloc.h, auf die in Zeile 237 verwiesen wird, ersetzt und abgedeckt
zend Die Datei /zend_gc.h beginnt in Zeile 202
/* The following macroses override macroses from zend_alloc.h */#undef ALLOC_ZVAL#define ALLOC_ZVAL(z) \ do {\ (z) = (zval*)emalloc(sizeof(zval_gc_info));\ GC_ZVAL_INIT(z);\ } while (0)
Die Definition des Makros ALLOC_ZVAL in zend_alloc.h besteht darin, den Speicherplatz einer Zval-Struktur zuzuweisen. Das neue ALLOC_ZVAL-Makro weist ein zval_gc_info-Strukturmakro zu. Die Struktur von zval_gc_info ist wie folgt:
Beginnen Sie in Zeile 91 der Datei zend/zend_gc.h:
typedef struct _zval_gc_info { zval z; union { gc_root_buffer *buffered; struct _zval_gc_info *next; } u;} zval_gc_info;
Das erste Mitglied von zval_gc_info ist die zval-Struktur, die sicherstellt, dass sie am Anfang ausgerichtet ist des mit der zval-Variablen zugewiesenen Speichers, sodass er als zval verwendet werden kann, wenn der Zeiger vom Typ zval_gc_info umgewandelt wird. Informationen zu gc_root_buffer usw. werden später in der Struktur und Implementierung vorgestellt. Es definiert die Cache-Struktur des PHP-Garbage-Collection-Mechanismus. GC_ZVAL_INIT wird verwendet, um zval_gc_info zu initialisieren, das zval ersetzt. Es setzt das gepufferte Feld des Mitglieds u in zval_gc_info auf NULL. Dieses Feld hat nur einen Wert, wenn es in den Garbage Collection-Puffer gestellt wird, andernfalls ist es immer NULL.
Da alle Variablen in PHP in Form von zval-Variablen vorliegen, wird zval hier durch zval_gc_info ersetzt, wodurch der Garbage-Collection-Mechanismus erfolgreich in das ursprüngliche System integriert wird.
Das fühlt sich ein bisschen wie objektorientierter Polymorphismus an.
[Speichermethode des Garbage-Collection-Mechanismus]
Knotenstruktur:
typedef struct _gc_root_buffer { struct _gc_root_buffer *prev;/* double-linked list */ struct _gc_root_buffer *next; zend_object_handle handle;/* must be 0 for zval */ union { zval *pz; zend_object_handlers *handlers; } u;} gc_root_buffer;
Offensichtlich (siehe Kommentare, obwohl es in PHP nur sehr wenige Kommentare gibt, handelt es sich bei einigen nur um verworrene Kommentare). eine doppelt verkettete Liste.
Die pz-Variable in der Union ist offensichtlich die zuvor definierte polymorphe zval_gc_info-Struktur, sodass ihr aktueller Knotenzeiger in der verknüpften Liste übergeben werden kann ((zval_gc_info*)(pz))->u .buffered, aber Wenn man sich den Quellcode ansieht, wird diese Aufrufmethode an vielen Stellen verwendet. Warum nicht ein neues Makro erstellen? Liegt es daran, dass ich Angst habe, zu viele Makros zu haben? Nein, PHP ist dafür bekannt, viele Makros zu haben, und es gibt viele Makros, die mehr verschachtelte Makros haben als dieses. Ich weiß es nicht. Darüber hinaus sind Handle und andere Strukturen speziell auf Objektvariablen ausgerichtet.
Der Puffer befindet sich in der globalen Variablen, auch gc verfügt über ein eigenes globales Variablenzugriffsmakro GC_G(v). In ähnlicher Weise unterscheidet sich das globale Variablenzugriffsmakro unter ZTS. Realisierung.
Die in zend_gc.h definierten globalen Variablen lauten wie folgt:
typedef struct _zend_gc_globals { zend_bool gc_enabled;/* 是否开启垃圾收集机制 */ zend_bool gc_active;/* 是否正在进行 */ gc_root_buffer *buf;/* 预分配的缓冲区数组,默认为10000(preallocated arrays of buffers) */ gc_root_buffer roots;/* 列表的根结点(list of possible roots of cycles) */ gc_root_buffer *unused;/* 没有使用过的缓冲区列表(list of unused buffers) */ gc_root_buffer *first_unused;/* 指向第一个没有使用过的缓冲区结点(pointer to first unused buffer) */ gc_root_buffer *last_unused;/* 指向最后一个没有使用过的缓冲区结点,此处为标记结束用(pointer to last unused buffer) */ zval_gc_info *zval_to_free;/* 将要释放的zval变量的临时列表(temporaryt list of zvals to free) */ zval_gc_info *free_list;/* 临时变量,需要释放的列表开头 */ zval_gc_info *next_to_free;/* 临时变量,下一个将要释放的变量位置*/ zend_uint gc_runs;/* gc运行的次数统计 */ zend_uint collected; /* gc中垃圾的个数 */ // 省略...
[Farbmarkierung im Garbage-Collection-Mechanismus]
#define GC_COLOR 0x03 #define GC_BLACK 0x00#define GC_WHITE 0x01#define GC_GREY 0x02#define GC_PURPLE 0x03 #define GC_ADDRESS(v) \ ((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR))#define GC_SET_ADDRESS(v, a) \ (v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & GC_COLOR) | ((zend_uintptr_t)(a))))#define GC_GET_COLOR(v) \ (((zend_uintptr_t)(v)) & GC_COLOR)#define GC_SET_COLOR(v, c) \ (v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & ~GC_COLOR) | (c)))#define GC_SET_BLACK(v) \ (v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR))#define GC_SET_PURPLE(v) \ (v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) | GC_PURPLE))
In der Speicherverwaltung von PHP haben wir auch Ähnliches gesehen Das Letzte Bit dient als eine Art Markierung.
Hier werden die letzten beiden Ziffern der Speicherbelegung als Farbmarkierung der gesamten Struktur verwendet. Unter diesen bedeutet
Weiß Müll,
Lila zeigt an, dass er in den Puffer gelegt wurde.
Grau zeigt an, dass eine Refcount-Operation durchgeführt wurde, um den Refcount um eins zu reduzieren.
Schwarz ist die Standardfarbe, normal
[definiert durch zval Change]
PHP3.0-Version befindet sich in der Datei zend/zend.h, die wie folgt definiert ist:
struct _zval_struct { /* Variable information */ zvalue_value value;/* value */ zend_uint refcount__gc; zend_uchar type;/* active type */ zend_uchar is_ref__gc;};
In Versionen vor PHP3.0, z Als PHP5.2.9-Version befindet es sich in der Datei zend/zend.h. Die Definition lautet wie folgt:
struct _zval_struct { /* Variable information */ zvalue_value value;/* value */ zend_uint refcount; zend_uchar type;/* active type */ zend_uchar is_ref;};
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er wird für das Studium aller hilfreich sein. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website!
Verwandte Empfehlungen:
Eine kurze Diskussion des PHP-Quellcodes 31: Die Grundlagen der Heap-Schicht im PHP-Speicherpool
Eine kurze Diskussion des PHP-Quellcodes 30: PHP-Speicherpool Speicherschicht in
Das obige ist der detaillierte Inhalt vonEine kurze Diskussion des PHP-Quellcodes 33: Grundlagen des neuen Garbage Collection-Mechanismus (Garbage Collection) in PHP5.3. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!