Maison >développement back-end >tutoriel php >PHP Master | Meilleure compréhension de la collection de ordures de PHP
Les changements de temps et les termes changent en conséquence. Aujourd'hui, nous pourrions l'appeler "Recyclage des ressources PHP" plutôt que "recyclage des ordures". Cela reflète plus étroitement son essence: elle ne rejette pas simplement, mais la réutilisation des ressources qui ne sont plus utilisées. Cependant, il est plus courant de suivre l'histoire du "recyclage des ordures".
Points de base:
Programme généré des ordures
Le programme utilise des ressources, parfois de petites ressources, parfois de grandes ressources. Par exemple, les champs de données. Un programme peut définir un champ de données (comme un numéro de série) et les utiliser dans le programme. Une fois définie, ce champ de données occupera un espace mémoire, peut-être seulement quelques octets, mais toujours de l'espace. Étant donné que chaque machine ou environnement de programmation a limité l'espace disponible, l'espace restant réduira la quantité d'espace occupée par ce champ. À la fin du programme, le programme et tout espace qu'il consommeront disparaîtra et l'espace disponible total sera restauré à sa taille maximale. Mais que se passe-t-il si le programme ne se termine jamais? J'ai déjà écrit certains de ces programmes. Ce sont de beaux chefs-d'œuvre et je suis toujours heureux chaque fois que d'autres dans l'atelier remarquent que j'en ai créé un. Rien ne montre mieux vos capacités que d'avoir un grand ordinateur IBM par vous-même, et dans les compartiments environnants, une personne après une autre crie: "Hé, y a-t-il quelque chose de mal avec le système?" détourner l'attention de vous. Mais certains programmes sont même conçus pour fonctionner pour toujours, comme les démons et d'autres programmes de ce type. Au fur et à mesure qu'ils courent, la quantité de déchets qu'ils génèrent peuvent continuer à croître. Si les ressources verrouillées sont importantes, elle aura un réel impact négatif sur le système. Par conséquent, chaque langue doit avoir un moyen d'effacer les ressources orphelines, de les mettre à la disposition d'autres utilisateurs et de s'assurer que la quantité totale d'espace système disponible reste la même. Heureusement, PHP utilise une méthode à trois couches pour l'élimination des ordures.
Première couche - End of Scope
Tout d'abord, comme la plupart des langues, chaque fois que la portée se termine, tout dans cette portée est détruit et que toutes les ressources allouées sont libérées. Les portées peuvent couvrir les fonctions, les scripts, les séances, etc. Lorsque la lunette se termine, tout ce qu'il tient se termine avec lui. Bien sûr, vous pouvez libérer des ressources à tout moment en utilisant la fonction unset (). C'est l'une des raisons pour lesquelles les fonctions et les méthodes sont si importantes car elles mettent en place des lunettes, spécifient quand une utilisation particulière de la mémoire commence et se termine, et limite la durée des choses. Ils doivent être utilisés dans la mesure du possible, pas des entités mondiales.
Deuxième couche - Compte de citation
Deuxièmement, comme la plupart des langages de script, PHP utilise une technique appelée comptage de référence pour suivre le nombre d'entités qui utilisent une variable donnée. Lors de la création d'une variable dans un script PHP, PHP crée un petit "conteneur" nommé Zval qui se compose de la valeur attribuée à la variable plus deux autres informations: IS_REF et RefCount. Le conteneur ZVAL est stocké dans un tableau, et chaque portée (scripts, fonctions, méthodes, etc.) a un tableau. IS_REF est une simple valeur vraie / fausse indiquant si la variable fait partie de l'ensemble de référence, aidant ainsi PHP à déterminer s'il s'agit d'une variable simple ou d'une référence. RefCount est plus intéressant car il détient une valeur numérique indiquant le nombre de variables différentes utilisant cette valeur. Autrement dit, si vous définissez la variable $ dave = 6, RefCount sera défini sur 1. Si je dis $ programmère = $ dave, RefCount sera incrémenté à 2. PHP sait ne pas créer un deuxième zval pour la valeur 6; Ce RefCount diminuera à la fin du programme, soit lorsque nous quittons la portée de la fonction, soit lors de l'utilisation d'unset (). Lorsque RefCount atteint zéro, Zval sera détruit et toute mémoire qu'il détient est maintenant libérée. Bien sûr, il s'agit d'un exemple simple d'une variable simple. Lorsque vous parlez d'un tableau ou d'un objet, la situation est beaucoup plus compliquée car plusieurs zrefs seront créés pour plusieurs valeurs d'éléments dans le tableau, mais le traitement de base est le même. Cependant, si nous utilisons des tableaux dans un autre tableau, qui se produit fréquemment dans des scripts PHP plus complexes, des problèmes surviennent. Dans ce cas, lorsque la valeur du tableau d'origine est définie, le refroidissement de la valeur du tableau est défini sur 1, puis lorsque le tableau est associé à un autre tableau, le refroidissement est incrémenté à 2. Si la plage d'utilisation du deuxième réseau se termine, RefCount est décrémenté de 1. Nous sommes maintenant dans une situation où la valeur elle-même n'est plus associée à quoi que ce soit, mais le refrot du conteneur (zval) qui représente qu'il est encore supérieur à zéro. Le résultat final est que le stockage représenté par le tableau d'origine ne sera pas libéré et que la quantité de mémoire n'est désormais pas disponible pour quoi que ce soit. Souvent, nous pensons que ce stockage perdu est petit, mais ce n'est généralement pas le cas. Les tableaux peuvent être de très grandes choses de nos jours, et il est particulièrement problématique si le script qui se produit est un démon ou une autre fonction qui s'exécute presque en continu. Dans ce cas, la «fuite de mémoire» résultante peut avoir des conséquences catastrophiques pour les performances et même les capacités opérationnelles du serveur.
Le troisième étage - Recyclage formel des ordures
Évidemment, la compensation basée sur le nombre de références a ses limites, mais heureusement, PHP 5.3 offre une autre option pour aider cette situation. Le cas spécifique que nous voulons que le cycle de collecte des ordures résout est le cas où ZVAL diminue mais est toujours non nul. Fondamentalement, bouclez pour voir quelles valeurs peuvent être encore décrémentées, puis libérer les valeurs avec zéro. Ce qui se passe réellement, c'est que PHP suit tous les conteneurs racine (ZVAL). Cela se fait, que la collection des ordures soit ou non (car elle doit simplement le faire sans demander si la collecte des ordures est ou non, etc.). Ce tampon racine peut contenir jusqu'à 10 000 racines (taille fixe, mais cela peut être modifié). Lorsqu'il se remplit, le mécanisme de collecte des ordures commencera et commencera à analyser ce tampon. La première chose que fait la routine GC est d'itérer à travers le tampon racine et de diminuer tous les comptes Zval de 1. En faisant cela, il marque chaque balise avec une petite balise comme une coche afin qu'elle ne diminue la racine qu'une seule fois. Il itère ensuite et marque (cette fois en utilisant une petite ligne ondulée) tous les zvals dont le nombre réduit est nul. Les valeurs qui ne sont pas nulles augmenteront pour qu'ils reviennent à leurs valeurs d'origine. Enfin, il fait défiler à nouveau, effacer le zval non nul à partir du tampon et libérer le magasin avec la valeur de Zero RefCount. La collecte des ordures est toujours activée en PHP, mais vous pouvez le désactiver en utilisant la directive zend.enable_gc dans le fichier php.ini. Alternativement, vous pouvez le faire dans le script en appelant les fonctions gc_enable () et gc_disable (). Comme mentionné ci-dessus, si la collecte des ordures est activée, elle s'exécute lorsque la racine est pleine, mais vous pouvez remplacer ce paramètre et exécuter la collection à l'aide de la fonction GC_COLLECT_CYCLE () lorsque vous le voyez. Et, vous pouvez modifier la taille du tampon racine à l'aide de la valeur gc_root_buffer_max_entries en zend / zend_gc.c dans le code source PHP. Dans l'ensemble, cela vous permet de contrôler si et quand et où le GC fonctionne, ce qui est une bonne chose car il est un peu exigeant des ressources et peut donc ne pas être le genre de chose que vous courez à volonté.
quand l'utiliser
Étant donné que la collecte des ordures peut affecter les performances, il vaut la peine de prendre le temps de déterminer quand vous devez l'utiliser. Tout d'abord, n'oubliez pas que si vous l'exécutez publiquement (en utilisant la fonction GC_COLLECT_CYCLES ()), la collection formelle de déchets ne se produit pas avant que la table racine (10 000 entrées) ne se remplisse, et parce que ce tableau est au niveau de la portée, pour petit ce qui a gagné ' t se produire avec les fonctions. Devriez-vous l'utiliser sur de petits scripts? C'est à vous. Il est difficile de dire que les opérations de course comme la collection Garbage sont une mauvaise chose, mais si vous avez de petits scripts rapides qui commencent et se terminent et disparaissent, il n'y a peut-être pas beaucoup de récompense. Cependant, si votre serveur exécute de nombreux petits scripts qui restent persistants, cela peut en valoir la peine. La seule façon de savoir vraiment est de définir une référence pour votre application et de le voir. Bien sûr, si vous avez des scripts de longue date, en particulier ceux qui ne se terminent jamais, alors la collecte des ordures est cruciale si vous voulez empêcher le type de fuites de mémoire dont nous avons discuté ci-dessus. Peut-être plus important encore, nous devons toujours essayer de suivre de bons guides de programmation afin que nous minimions ou éliminions les variables globales et lions nos variables à la portée afin que même si nous avons des scripts de longue durée, cette mémoire peut être libérée à la fin de la fonction, Pas à la fin du script. Sachez également quand un tableau ou un objet de référence d'objet est utilisé dans un tableau, car cette situation peut entraîner des fuites de mémoire et est le véritable objectif du processus de collecte de déchets formel.
Images de Fotolia
PHP Recyclage des ordures FAQ (FAQ)
(La partie FAQ est omise ici parce que l'article est trop long et ne correspond pas à l'objectif pseudo-original. Le contenu de la partie FAQ est fortement coïncide peut être modifié après modification.)
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!