变量
$n1 = memory_get_usage();
$a = range(0, 5);
$n2 = memory_get_usage();
$b = $a;
$n3 = memory_get_usage();
$a = range(5, 10);
$n4 = memory_get_usage();
p($a);
p($b);
p($n2-$n1);
p($n3-$n2);
p($n4-$n3);
输入结果:
Array
(
[0] => 5
[1] => 6
[2] => 7
[3] => 8
[4] => 9
[5] => 10
)
Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] => 4
[5] => 5
)
272
0
272
memory_get_usage()为获取当前消耗内存,初始创建时 $a 耗内存275,将$a赋值给$b时消耗内存为0,最后修改$a时消耗内存272
从结果上来看赋值$b并没有重新开辟内存空间,因为PHP 中COW(Copy On Write) 会导致赋值是引用上一个变量的地址(内存不会发生太大变化),只有在发生 写 操作的时候,才会开辟新的内存地址,而当变量$a值又会开辟一块空间
引用变量
function p($var)
{
echo "\r\n";
print_r($var);
echo "\r\n";
}
$n1 = memory_get_usage();
$a = range(0, 5);
xdebug_debug_zval('a');
$n2 = memory_get_usage();
$b = &$a;
xdebug_debug_zval('a');
$n3 = memory_get_usage();
$a = range(5, 10);
xdebug_debug_zval('a');
$n4 = memory_get_usage();
p($a);
p($b);
p($n2-$n1);
p($n3-$n2);
p($n4-$n3);
输出:
a: (refcount=1, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)
a: (refcount=2, is_ref=1)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)
a: (refcount=2, is_ref=1)=array (0 => (refcount=0, is_ref=0)=5, 1 => (refcount=0, is_ref=0)=6, 2 => (refcount=0, is_ref=0)=7, 3 => (refcount=0, is_ref=0)=8, 4 => (refcount=0, is_ref=0)=9, 5 => (refcount=0, is_ref=0)=10)
Array
(
[0] => 5
[1] => 6
[2] => 7
[3] => 8
[4] => 9
[5] => 10
)
Array
(
[0] => 5
[1] => 6
[2] => 7
[3] => 8
[4] => 9
[5] => 10
)
408
24
0
初始创建时 $a 耗内存408,之所以和前面前面初始创建消耗内存不一样是因为xdebug_debug_zval也是会消耗内存的,将$a引用赋值给$b时消耗内存为24,最后修改$a时消耗内存0,并且$b的值也跟着修改
xdebug_debug_zval('a');refcount=1,表示当前有一个变量指向这个内存空间;
当$b=&a时,refcount=2, 说明2个变量都指向a的内存空间。is_ref=1,表示存在一个引用变量$b,消耗内存24。
当$a=range(5, 10);重新赋值时,内存消耗为0,并没有生成新的内存空间。分别输出$a和$b,可以看到他们2个的值都变成range(5, 10)。
采用了 引用(&),所以从第二步开始 refcount = 2,is_ref = 1(引用) ,引用状态下不开辟新的内存地址;
当变量修改时,所有变量也会一起发生修改,因为他们指向同一片内存空间