En PHP, le nom complet de gc est "Garbage Collection", qui signifie "garbage collection" en chinois. Il s'agit d'un mécanisme de gestion dynamique de la mémoire qui libère automatiquement les blocs de mémoire alloués qui ne sont plus nécessaires au programme. Le mécanisme GC permet aux programmeurs de ne pas trop se soucier de l'allocation de mémoire du programme, afin qu'ils puissent consacrer plus d'énergie à la logique métier.
L'environnement d'exploitation de ce tutoriel : système Windows 7, PHP version 7.1, ordinateur DELL G3
En PHP, le nom complet de gc est "Garbage Collection", qui signifie "garbage collection" en chinois, et est une sorte de mécanisme de gestion dynamique de la mémoire.
Le mécanisme de collecte des déchets (GC) libère automatiquement les blocs de mémoire alloués qui ne sont plus nécessaires au programme. Le processus de récupération automatique de la mémoire est appelé garbage collection.
Le mécanisme de récupération de place (GC) permet aux programmeurs de ne pas trop se soucier de l'allocation de mémoire du programme, afin qu'ils puissent consacrer plus d'énergie à la logique métier.
Parmi les différentes langues populaires aujourd'hui, le mécanisme de collecte des ordures est une caractéristique commune de la nouvelle génération de langues.
Génération de garbage
Les types complexes en PHP7, tels que les chaînes, les tableaux, les objets, etc., ont un gc dans l'en-tête. La fonction de ce gc est de prendre en charge le garbage collection. Lorsqu'une variable est attribuée ou transférée, le numéro de référence de la valeur sera augmenté lorsque la variable est libérée par unset, return, etc., le numéro de référence sera soustrait après la soustraction, si le refcount devient 0, le la valeur sera libérée directement. Il s’agit du processus de recyclage de base des variables.
Cependant, il existe un problème que ce mécanisme ne peut pas résoudre, à savoir le problème des références circulaires.
Qu'est-ce qu'une référence circulaire ? En termes simples, la valeur stockée dans la variable fait référence à la variable elle-même. Cette comparaison se produit souvent avec des variables de types tableau et objet.
Parlons d'abord des références, c'est-à-dire du type zend_reference. Il s'agit d'un nouveau type de variable en PHP7. Lorsque l'opération "&" est utilisée sur une variable, une nouvelle structure intermédiaire zend_reference sera en fait créée. à la structure de valeur correspondante.
Par exemple :
// 当进行如下赋值操作时 $a = 'hello'; // $a -> zend_string $b = $a; // $b,$a -> zend_string $c = &$b; // $c,$b -> zval(type = IS_REFERENCE, refcount = 2) -> zend_string
finira par devenir comme ceci :
C'est-à-dire que le zval de $b et $c pointe vers la zend_string finale via la structure intermédiaire zend_reference.
Retour à la question des références circulaires, voici un exemple de références circulaires de tableau :
$a = [1]; $a[] = &$a; unset($a);
Après avoir utilisé l'opération &, la variable a devient un type de référence et le nombre de références refcount est de 2, et elle est affectée au sien les éléments, c'est-à-dire les variables a, deviennent eux-mêmes auto-référencés.
Les détails sont les suivants :
Après la désactivation, cela ressemblera à l'image ci-dessous :
C'est-à-dire que le type zval où se trouve $a est devenu IS_UNDEF, et le nombre de références du La structure zend_reference est réduite de 1 , mais elle est toujours supérieure à 0. À ce stade, cette partie de la structure devient un déchet si elle n'est pas traitée, cela peut provoquer une fuite de mémoire. Ici, vous avez besoin du garbage collector pour collecter cette partie dans le tampon, puis la recycler.
Processus de recyclage
Si le refcount d'une variable est supérieur à 0 après sa réduction, PHP n'effectuera pas immédiatement l'identification des déchets et le recyclage sur cette variable, mais la mettra dans un tampon jusqu'à ce que le tampon soit plein ( 10000 valeurs) sont ensuite traitées uniformément. Ce qui est ajouté au tampon est le gc dans la variable zend_value. Actuellement, les déchets n'apparaîtront que sous deux types : les tableaux et les objets. Références d'attributs de membres. En raison de l'objet lui-même, les autres types n'auront pas de membres dans de telles variables faisant référence aux variables elles-mêmes, donc le garbage collection ne traitera que ces deux types de variables.
gc La structure de zend_refcounted_h est la suivante :
typedef struct _zend_refcounted_h { uint32_t refcount; // 记录 zend_value 的引用数 union { struct { zend_uchar type, // zend_value的类型, 与zval.u1.type一致 zend_uchar flags, uint16_t gc_info // GC信息,记录在 gc 池中的位置和颜色,垃圾回收的过程会用到 } v; uint32_t type_info; } u; } zend_refcounted_h;
Une variable ne peut être ajoutée au tampon qu'une seule fois Afin d'éviter des ajouts répétés, zend_refcounted_h.gc_info sera défini sur GC_PURPLE après l'ajout de la variable, qui est marquée en violet. , et ne sera pas inséré à plusieurs reprises à l'avenir.
Le tampon de récupération est une liste doublement chaînée. Lorsque le tampon est plein, le processus de vérification des déchets sera lancé : parcourez le tampon, parcourez tous les membres de la variable actuelle, puis réduisez le refcount du membre de 1 (si le Le membre contient également des sous-membres) Effectuez également un parcours récursif, c'est-à-dire un parcours en profondeur d'abord), et enfin vérifiez la référence de la variable actuelle. Si elle est réduite à 0, c'est une poubelle. Le principe de base de cet algorithme est le suivant : les déchets sont causés par les membres se référant à eux-mêmes, puis réduisez les références à tous les membres. S'il s'avère que le refcount de la variable finale elle-même devient 0, cela signifie que toutes ses références proviennent de la sienne. membres, c'est-à-dire ailleurs. Si vous ne l'utilisez plus, c'est un déchet et il faut le recycler. Sinon, cela signifie qu'il ne s'agit pas d'un déchet et qu'il doit être supprimé du tampon. Le processus spécifique est le suivant :
(1) Commencez à parcourir à partir des racines de la liste chaînée du tampon, marquez la valeur actuelle en gris (définissez zend_refcounted_h.gc_info sur GC_GREY), puis effectuez un parcours en profondeur d'abord des membres de la valeur actuelle, réduisez le refcount du valeur du membre par 1, et marquez-la également comme grise ;
(2) Parcourez à plusieurs reprises la liste des liens du tampon pour vérifier si la référence de valeur actuelle est 0. Si elle est 0, cela signifie que c'est effectivement une poubelle. Marquez-la comme blanche (. GC_WHITE). S'il n'est pas 0, il exclut toutes les références de lui-même. La possibilité de membres indique qu'il existe des références externes et n'est pas une poubelle à ce stade, car le refcount des membres est réduit de 1 à l'étape (1). , il doit être restauré à nouveau, une traversée approfondie de tous les membres est effectuée et le nombre de références des membres est augmenté de 1. En même temps Marqué en noir
(3) Parcourez à nouveau la liste chaînée du tampon, supprimez les non-GC_WHITE ; les nœuds de la liste chaînée racines, et enfin la liste chaînée racines seront tous de vraies ordures, et enfin effaceront ces ordures.
Apprentissage recommandé : "Tutoriel vidéo PHP"
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!