php中COW机制

  COW(copy on write)是内存优化的常见手段,在php中也采用了这种方式来优化内存。COW:写时复制,即只有当对其中一个或多个变量进行写操作的时候,才会复制一份内存,对其内容进行修改。下面看一个例子

<?php

echo '程序开始时内存的使用情况:';
var_dump(memory_get_usage());

//定义一个变量a
$a = range(0, 9);
echo '定义变量a后内存的使用情况:';
var_dump(memory_get_usage());

//定义一个变量b,将变量a的值赋值给b
$b = $a;    //使用相同的内存
echo '定义了变量b,将变量a的值赋值给b后,内存的使用情况:';
var_dump(memory_get_usage());

echo '修改a的值后,内存的使用情况:';
$a = range(9, 0);
var_dump(memory_get_usage());

代码运行结果:
php程序内存使用测试
可以看出,在定义了变量a后,内存的使用量为359888,当定义变量b,并将变量b的值初始化为变量a,此时,php给程序分配的内存并没有发生改变!说明变量a和b使用同一块内存空间,当给变量a重新赋值时,即修改变量a的值后,发现内存量有所增加,从而验证了php中COW机制。

引用是比较特殊的,下面我们再来看一下,直接看栗子吧~

<?php

echo '程序开始时内存的使用情况:';
var_dump(memory_get_usage());
//定义一个变量a
$a = range(0, 9);
echo '定义变量a后内存的使用情况:';
var_dump(memory_get_usage());

//定义一个引用变量b,将变量a的值赋值给b
$b = &$a;    

echo '定义了变量b,将变量a的值赋值给b后,内存的使用情况:';
var_dump(memory_get_usage());

echo '修改a的值后,内存的使用情况:';
$a = range(9, 0);
var_dump(memory_get_usage());

代码运行结果:
php引用变量内存测试
与上段代码不同的是,变量b声明为a的引用,在定义变量b之后,程序所占的内存增加的很好,并没有定义a时增加的多,由此可以看出,并没有为变量单独分配内存,因为在php中,引用是用不同的名字访问相同的变量内容(变量和变量内容是不同的概念),在修改变量a的值后,改变的是两个变量名指向的共同的变量内容,所以并没有内存的增加。我们再来看一下使用xdebug调试一下,代码修改后如下:

<?php

//定义一个变量a
$a = range(0, 9);
echo '定义变量a后:<br />';

xdebug_debug_zval('a');

//定义一个引用变量b,将变量a的值赋值给b
$b = &$a;

echo '定义了变量b,将变量a的值赋值给b后:<br />';
xdebug_debug_zval('b');

echo '修改a的值后:<br />';
$a = range(9, 0);
xdebug_debug_zval('b');

代码运行结果:
xdebug调试引用变量
由此可得:定义了a的引用b后,refcount的值为2,即使修改了a的值,引用数并没有减少,只是两个变量名指向的共同的变量内容的值发生了改变。由于引用是共用一块变量内容,所以即使是通过其中一个变量名修改变量内容的值,也不会发生内存的复制。
COW是优化内存的一种手段,是的值相同的变量可以共用同一块内存,从而减少了内存的分配,提高了内存的使用率。

猜你喜欢

转载自blog.csdn.net/qq_38253837/article/details/80340505