PHP如何为变量分配和释放内存?

12
我想知道PHP何时释放用于变量的内存。
例如:
function foo(){
  $foo = 'data';
  return $foo;  // <- is the memory space for `$foo` emptied at this point?
}

比起以下的速度,它更慢:
function foo(){
  return 'data'; 
}

?


我们可以问一下你为什么在问吗?如果我没记错的话,底层的Zend引擎使用了写时复制技术,所以在大多数情况下实际上并不重要。你是遇到了内存不足的问题吗? - Charles
1
(参考)垃圾回收 - Gordon
不,我只是好奇 :) 但我承认你的回答可能会影响我未来的编码风格 :) - Alex
一般来说,像 PHP(或其他任何语言)这样的维护语言,可能已经有人想到了并实现了最有效的解决方案。虽然这并不总是正确的,但通常情况下是如此。 - fingerman
1个回答

10

好的,让我们找出答案!

<?php
$checkpoints = array( 'start' => memory_get_usage() );

$checkpoints['before defining demo1'] = memory_get_usage();
function demo1() { $foo = 'data'; return $foo; }
$checkpoints['after defining demo1'] = memory_get_usage();

$checkpoints['before defining demo2'] = memory_get_usage();
function demo2() { return 'data'; }
$checkpoints['after defining demo2'] = memory_get_usage();


$checkpoints['before calling demo1'] = memory_get_usage();
demo1();
$checkpoints['after calling demo1'] = memory_get_usage();

$checkpoints['before calling demo2'] = memory_get_usage();
demo2();
$checkpoints['after calling demo2'] = memory_get_usage();

$checkpoints['before calling demo1 with storage'] = memory_get_usage();
$storage1 = demo1();
$checkpoints['after calling demo1 with storage'] = memory_get_usage();

$checkpoints['before calling demo2 with storage'] = memory_get_usage();
$storage2 = demo2();
$checkpoints['after calling demo2 with storage'] = memory_get_usage();

echo '<pre>';
print_r($checkpoints);

$last_key = 'start';
foreach($checkpoints as $key => $value) {
    echo "{$key} - {$last_key} = ", ($value - $checkpoints[$last_key]), "\n";
    $last_key = $key;
}
在PHP 5.3.6下,我的输出是:
Array
(
    [start] => 321920
    [before defining demo1] => 322188
    [after defining demo1] => 322788
    [before defining demo2] => 322880
    [after defining demo2] => 323188
    [before calling demo1] => 323280
    [after calling demo1] => 323368
    [before calling demo2] => 323464
    [after calling demo2] => 323552
    [before calling demo1 with storage] => 323692
    [after calling demo1 with storage] => 323896
    [before calling demo2 with storage] => 324000
    [after calling demo2 with storage] => 324204
)

然后

start - start = 0
before defining demo1 - start = 268
after defining demo1 - before defining demo1 = 600
before defining demo2 - after defining demo1 = 92
after defining demo2 - before defining demo2 = 308
before calling demo1 - after defining demo2 = 92
after calling demo1 - before calling demo1 = 88
before calling demo2 - after calling demo1 = 96
after calling demo2 - before calling demo2 = 88
before calling demo1 with storage - after calling demo2 = 140
after calling demo1 with storage - before calling demo1 with storage = 204
before calling demo2 with storage - after calling demo1 with storage = 104
after calling demo2 with storage - before calling demo2 with storage = 204

很可能在调用 demo1demo2 并且不输出结果时,内存增加是由于创建用于存储内存使用情况的变量造成的。

然而,在这两个示例中,无论是直接返回数据还是将其赋值给变量再返回,对于给定数据,它们都具有完全相同的内存使用情况

结论: 在这个简单的测试中,PHP 似乎足够聪明,不会不必要地复制字符串变量 - 但请注意两个函数之间的内存使用差异。仅声明 demo1 函数所需的内存比声明 demo2 多几百字节。


1
非常感谢。我想我会尽可能使用第二种方法:D - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接