【问题标题】:How does PHP assign and free memory for variables?PHP 如何为变量分配和释放内存?
【发布时间】:2011-08-23 16:29:27
【问题描述】:

我想知道 PHP 什么时候释放用于变量的内存

例如

function foo(){
  $foo = 'data';
  return $foo;  // <- is the memory space for `$foo` emptied at this point?
}

是否比:

function foo(){
  return 'data'; 
}

?

【问题讨论】:

  • 我们能问一下您为什么要问吗? IIRC,底层 Zend 引擎使用写时复制,所以在大多数情况下它可能实际上并不重要。您是否遇到内存不足的问题?
  • (参考) Garbage Collection
  • 不,我只是好奇 :) 但我承认你的回答可能会影响我未来的编码风格 :)
  • 一般来说,像 php (或任何其他相关的)这样的维护语言可能已经有人已经想到了这一点 - 并植入了最有效的解决方案。虽然这并不总是正确的 - 它经常是。

标签: php memory variables memory-management php-internals


【解决方案1】:

好吧,让我们找出答案!

<?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

在初始调用 demo1 和 demo2 期间,丢弃输出的内存增加很可能是由于创建了用于存储内存使用的变量。

但是,这里的底线是两个存储示例,其中直接返回数据并在返回之前将其分配给变量导致给定数据的完全相同的内存使用。 p>

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

【讨论】:

  • 非常感谢。我想我会尽可能使用第二种方法:D
猜你喜欢
  • 2020-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-09
相关资源
最近更新 更多