Maison  >  Article  >  développement back-end  >  Gestion de la mémoire des variables PHP

Gestion de la mémoire des variables PHP

不言
不言original
2018-04-18 10:11:101877parcourir

Cet article présente principalement la gestion de la mémoire des variables PHP. Il a une certaine valeur de référence. Maintenant, je le partage avec tout le monde. Les amis dans le besoin peuvent s'y référer

Chaque langage informatique a besoin de conteneurs pour enregistrer les variables. données. Dans certains langages, les variables ont des types spécifiques, tels que des chaînes, des tableaux, des objets, etc. Par exemple, C et Pascal entrent dans cette catégorie. PHP n'a pas ce type. En PHP, une variable qui est une chaîne sur une ligne peut devenir un nombre sur la ligne suivante. Les variables peuvent souvent être facilement converties entre différents types, même automatiquement. Une grande partie de la raison pour laquelle PHP est un langage simple et puissant est qu’il possède des variables faiblement typées. Mais cela peut parfois entraîner des problèmes intéressants.

En interne dans PHP, les variables sont stockées dans un conteneur appelé zval. Il contient non seulement la valeur de la variable, mais également le type de la variable. Python, comme PHP, possède également une étiquette pour marquer le type de variable. Le conteneur de variables contient certains champs que le moteur Zend utilise pour distinguer s'ils sont référencés ou non. Il contient également le nombre de références de cette valeur.

Les variables sont stockées dans une table de symboles équivalente à un tableau associatif. Ce tableau est codé par noms de variables et pointe vers des conteneurs contenant ces variables. Comme indiqué ci-dessous :


Comptage de références

PHP essaie d'être intelligent lors de la copie de variables (telles que $a = $b). "=" est également appelé opérateur d'affectation. Lors de l'exécution d'une opération d'affectation, le moteur Zend ne créera pas une nouvelle fenêtre de variable, mais augmentera le champ refcount de la fenêtre de variable. Vous pouvez imaginer que lorsque cette variable est une énorme chaîne ou un énorme tableau, cela augmentera la quantité de mémoire. enregistré. Comme le montre la figure ci-dessous :


Étape 1 : La variable a contient le texte « c'est ». Par défaut, le nombre de références est égal à 1

Étape 2 : Attribuez la variable $a à $b et $c. Aucun nouveau conteneur de variable n'est généré ici, seul le refcount est augmenté de 1 à chaque fois qu'une variable est affectée. Étant donné que deux opérations d'affectation sont effectuées ici, refcount deviendra finalement 3.

Maintenant, vous vous demandez peut-être ce qui se passe lorsque la variable $c change. En fonction de la valeur de refcount, il sera traité de deux manières différentes. Si refcount est égal à 1, le conteneur de variables mettra à jour sa valeur (et peut-être aussi son type). Si refcount est supérieur à 1, un conteneur de variables contenant la nouvelle valeur (et le type) sera créé. Comme le montre la troisième étape de la figure 2, la valeur refcount du conteneur de variables où se trouve la variable $a est soustraite de un. Désormais, la valeur refcount est 2 et la valeur refcount du conteneur nouvellement créé est 1. Lorsque la fonction unset est utilisée sur une variable, la valeur refcount du conteneur où se trouve la variable sera réduite de un, comme indiqué à l'étape 4 de la figure. Si la valeur de refcount est inférieure à 1, le Zend Engine traduira le conteneur de variables, comme indiqué à l'étape 5 de la figure.

Passer des variables aux fonctions

En plus de la table de symboles globale partagée par tous les scripts, chaque fonction définie par l'utilisateur créera sa propre table de symboles lorsqu'elle sera appelée. Utilisée pour stocker ses propres variables. Lorsqu'une fonction est appelée, le moteur Zend créera une telle table de symboles, et la table de fonctions sera publiée au retour de la fonction. Une fonction est renvoyée soit via une instruction return, soit parce que la fonction se termine (Note du traducteur : les fonctions qui ne renvoient pas renverront NULL par défaut). Comme indiqué ci-dessous :


La figure 3 détaille comment les variables sont transmises aux fonctions.

Dans la première étape, nous attribuons "thisis" à la variable $a, puis nous passons cette variable à la variable $s de la fonction do_something().

Dans la deuxième étape, vous pouvez voir qu'il s'agit de la même opération que l'affectation de variable (similaire au $b = $a que nous avons mentionné dans la section précédente), sauf qu'elle est stockée dans une table de symboles différente. (tableau des symboles de fonction), et le décompte de références est incrémenté de 2 au lieu de 1. La raison en est que la pile de fonctions contient également une référence à ce conteneur de variables.

La troisième étape, lorsque nous attribuons une nouvelle valeur à la variable $s, le refcount du conteneur de variable d'origine est réduit de 1 et un conteneur de variable contenant la nouvelle valeur est créé.

Dans la quatrième étape, nous renvoyons une variable via l'instruction return. La variable renvoyée obtient une entité de la table des symboles globale et incrémente son refcount de 1. Lorsque la fonction se termine, la table des symboles de la fonction est détruite. Pendant le processus de destruction, le moteur Zend parcourra chaque variable de la table des symboles et réduira sa valeur de refcount. Lorsque la valeur de refoulement du conteneur de variables devient 0, le conteneur de variables sera détruit. Comme vous pouvez le constater, en raison du mécanisme de comptage de références de PHP, le conteneur de variables n'est pas copié depuis la fonction. Si la variable $s n'a pas été modifiée à la troisième étape, les variables $a et $b pointeront toujours vers le même conteneur de variables (le refcount de ce conteneur est 2). Dans ce cas, l'instruction $a = "this is" ne créera pas de copie du conteneur de variables.

Recommandations associées :

Mécanisme de copie sur écriture des variables 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!

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