Maison >développement back-end >tutoriel php >Une brève discussion du code source PHP 33 : bases du mécanisme de récupération de place nouvellement ajouté (Garbage Collection) dans PHP5.3

Une brève discussion du code source PHP 33 : bases du mécanisme de récupération de place nouvellement ajouté (Garbage Collection) dans PHP5.3

不言
不言original
2018-06-29 10:00:341806parcourir

Cet article présente principalement les bases du code source PHP trente-trois : le mécanisme de récupération de place nouvellement ajouté (Garbage Collection) de PHP5.3 Il a une certaine valeur de référence. Maintenant, je le partage avec vous.

Parlons brièvement du code source PHP 33 : Les bases du nouveau mécanisme de collecte des ordures (Garbage Collection) dans PHP5.3
PHP5.3 a un nouveau mécanisme de collecte des ordures, qui est dit très avancé. Ceci dit m'a séduit de voir sa mise en œuvre avancée.
Pour la documentation officielle, veuillez cliquer sur Garbage Collection
Adresse de la version chinoise : http://docs.php.net/manual/zh/features.gc.php
[Méthode d'intégration du mécanisme de collecte des ordures]
Le fichier zend_gc.h est référencé à la ligne 749 de zend.h : #include "zend_gc.h"
Remplaçant et couvrant ainsi ALLOC_ZVAL et d'autres macros dans le fichier zend_alloc.h référencé à la ligne 237
zend /zend_gc.h commence à la ligne 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)

La définition de la macro ALLOC_ZVAL dans zend_alloc.h est d'allouer l'espace mémoire d'une structure zval. La nouvelle macro ALLOC_ZVAL alloue une macro de structure zval_gc_info. La structure de zval_gc_info est la suivante :
À partir de la ligne 91 du fichier 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;

Le premier membre de zval_gc_info est la structure zval, qui garantit sa cohérence avec la mémoire allouée avec la variable zval. Commencez l'alignement afin qu'elle puisse être utilisée comme zval lors du lancement d'un pointeur de type zval_gc_info. À propos de gc_root_buffer, etc. sera présenté plus tard dans la structure et l'implémentation. Il définit la structure du cache du mécanisme de récupération de place PHP. GC_ZVAL_INIT est utilisé pour initialiser zval_gc_info qui remplace zval. Il définira le champ tamponné du membre u dans zval_gc_info sur NULL. Ce champ n'aura une valeur que lorsqu'il sera placé dans le tampon de récupération de place, sinon il sera toujours NULL.

Puisque toutes les variables en PHP existent sous la forme de variables zval, zval est remplacé ici par zval_gc_info, intégrant ainsi avec succès le mécanisme de récupération de place dans le système d'origine.
Cela ressemble un peu à un polymorphisme orienté objet.

[Méthode de stockage du mécanisme de récupération de place]
Structure du nœud :

 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;

Évidemment (voir les commentaires, bien qu'il y ait peu de commentaires en PHP, certains sont purement enchevêtrés Remarque), ceci est une liste doublement chaînée.

La variable pz dans l'union est évidemment la structure polymorphe zval_gc_info définie précédemment, donc son pointeur de nœud actuel dans la liste chaînée peut être passé ((zval_gc_info*)(pz))->u .buffered, mais en regardant le code source, cette méthode d'appel est utilisée dans de nombreux endroits, pourquoi ne pas créer une nouvelle macro ? Est-ce parce que j'ai peur d'avoir trop de macros ? Non, PHP est célèbre pour avoir de nombreuses macros, et il existe de nombreuses macros qui ont plus de macros imbriquées que celle-ci. je ne sais pas. De plus, les handles et autres structures sont spécifiquement destinés aux variables d’objet.

Le tampon est dans la variable globale. Comme les variables globales des autres modules, gc a également sa propre macro d'accès aux variables globales GC_G(v). De même, la macro d'accès aux variables globales est différente sous ZTS ou non. réalisation.
Les variables globales définies dans zend_gc.h sont les suivantes :

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中垃圾的个数 */ // 省略...

[Marquage de couleur dans le mécanisme de récupération de place]

 #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))

Nous jetons également un œil à la mémoire de PHP gestion À quelque chose comme utiliser le dernier bit comme type de marquage.

Ici, les deux derniers chiffres de l'allocation de mémoire sont utilisés comme marque de couleur de l'ensemble de la structure. Parmi eux,
le blanc indique les déchets
le violet indique qu'ils ont été mis dans le tampon
le gris indique qu'une opération de refcount a été effectuée pour réduire le refcount d'un
le noir est la couleur par défaut, normal

[défini par zval Change]
La version PHP3.0 est dans le fichier zend/zend.h, qui est défini comme suit :

struct _zval_struct {
/* Variable information */
zvalue_value value;/* value */
zend_uint refcount__gc;
zend_uchar type;/* active type */
zend_uchar is_ref__gc;};

La version avant php3. 0, comme la version php5.2.9, est dans le fichier zend/zend. h, sa définition est la suivante :

struct _zval_struct {
/* Variable information */
zvalue_value value;/* value */
zend_uint refcount;
zend_uchar type;/* active type */
zend_uchar is_ref;};

Ce qui précède est l'intégralité du contenu de cet article. J'espère qu'il vous sera utile. l'étude de tout le monde. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !

Recommandations associées :

Une brève discussion du code source PHP 32 : couche emalloc/efree et couche de tas dans le pool de mémoire PHP

Une brève discussion du code source PHP 31 : les bases de la couche de tas dans le pool de mémoire PHP

Une brève discussion du code source PHP 30 : le pool de mémoire PHP Couche de stockage dans

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn