Copy-on-Write (également abrégé en COW), comme son nom l'indique, copie en fait une copie de la mémoire pour la modifier lors de l'écriture. COW a d'abord été utilisé dans les systèmes * nix pour optimiser l'utilisation des threads et de la mémoire, puis a été largement utilisé dans divers langages de programmation, tels que STL de C++, etc. Dans le noyau PHP, COW est également la principale méthode d'optimisation de la mémoire. Dans la discussion précédente sur les variables et la mémoire, le comptage de références joue un rôle d'identification crucial dans la destruction et le recyclage des variables. Le but du comptage de références est de permettre à COW de fonctionner normalement, obtenant ainsi une utilisation optimale de la mémoire.
Le rôle de la copie sur écriture
Ce qui suit est un morceau de code :
<?php var_dump(memory_get_usage());//先打印出当前内存情况 $arr = array_fill(0, 100000, 'tioncico');//生成一个0-100000键的数组 var_dump(memory_get_usage());//打印内存 $arr_copy = $arr;//把数组赋值给另一个 var_dump(memory_get_usage());//打印内存 $j=1; foreach($arr_copy as $i) {//循环遍历该数组键值查看内存情况 $j += count($i); } var_dump(memory_get_usage());//打印内存
En d'autres termes, même si nous n'utilisons pas de références, les variables PHP transmettent des valeurs et attribuent des valeurs, pointant toutes vers la même mémoire, mais quoi se produit si la valeur de $arr_copy change ?<?php
var_dump(memory_get_usage()); //$tipi = array_fill(0, 3, 'php-internal'); //不用array_fill的原因可自己试着打印下 $tipi[0]='php-internal'; $tipi[1]='php-internal'; $tipi[2]='php-internal'; var_dump(memory_get_usage()); $copy = $tipi; xdebug_debug_zval('tipi', 'copy'); var_dump(memory_get_usage()); $copy[0] = '123'; xdebug_debug_zval('tipi', 'copy'); var_dump(memory_get_usage());
Les résultats sont les suivants : (Remarque : les résultats sont sous le environnement web php5.6, et les références de php7 sont différentes)
On voit que lorsque $arr attribue la valeur à $arr_copy, il n'y a pas de changement évident dans la mémoire d'exécution. Augmentez directement la quantité de mémoire de 5443320
Même lors du parcours foreach suivant, la mémoire n'est pas augmentée.
Parce que lorsque $arr est assigné à $arr_copy, il n'est pas dans La valeur entière de $arr est copiée dans la mémoire, mais la valeur de $arr_copy est pointée vers $arr, ce qui équivaut à lors de la récupération du données de $arr_copy, il pointe toujours vers la mémoire où $arr stocke la valeur
En d'autres termes, même si nous n'utilisons pas de références, lorsque les variables PHP transmettent des valeurs et attribuent des valeurs, elles pointent toutes dans la même mémoire, mais que se passe-t-il si la valeur de $arr_copy change
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Les résultats sont les suivants : (Remarque : ce résultat est sous l'environnement web php5.6, et les références de php7 sont différentes)
On voit que lorsque la valeur de $copy[0] change, php réappliquera la mémoire pour $copy[0], puis lui attribuera une nouvelle valeur, mais cela n'affectera pas l'état de la mémoire des autres valeurs. La granularité minimale de la copie sur écriture est la structure zval. Pour les collections de structures zval (telles que les tableaux et les objets, etc.), lorsque la mémoire doit être copiée, les objets complexes sont décomposés dans la plus petite granularité pour le traitement. De cette façon, lorsqu'une certaine partie d'un objet complexe en mémoire est modifiée, il n'est pas nécessaire de « séparer » tous les éléments de l'objet dans une copie mémoire, économisant ainsi l'utilisation de la mémoire.
(xdebug_debug_zval dans l'article est une fonction de l'extension xdebug, utilisée pour afficher les informations de référence des variables)
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!