在PHP中取消变量设置有多重要?

34

我对PHP还比较新,想知道:

在PHP中取消变量的设置有多重要?

我知道在像C这样的语言中,我们释放分配的内存以防止泄漏等问题。 在完成变量使用后使用unset命令,是否会显着提高应用程序的性能?

此外,是否有任何基准测试可以比较使用unset和不使用unset之间的差异?


(相关内容)http://www.php.net/manual/en/features.gc.refcounting-basics.php和http://blog.preinheimer.com/index.php?/archives/354-Memory-usage-in-PHP.html - Gordon
谢谢提供这些链接。它们提供了很好的解释。 - dd0x
4个回答

55

请参考这个例子(以及我在问题下面链接的文章):

$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";      // 120172
echo memory_get_peak_usage() . "<br>\n"; // 121248

$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";      // 120172
echo memory_get_peak_usage() . "<br>\n"; // 201284

正如您所看到的,PHP曾经一度使用了近乎双倍的内存。这是因为在将“x”字符串分配给$x之前,PHP会在内存中构建新字符串,同时还会保留先前变量的内存。可以通过使用unset来防止这种情况发生。

另一个例子:

for ($i=0; $i<3; $i++) {
    $str = str_repeat("Hello", 10000);
    echo memory_get_peak_usage(), PHP_EOL;
}

这将输出类似于以下内容

375696
425824
425824

在第一次迭代中,在赋值之前$str仍然为空。但是在第二次迭代中,$str将保存生成的字符串。当第二次调用str_repeat时,它不会立即覆盖$str,而是首先在内存中创建要分配的字符串。因此,你最终得到了$str和它应该被赋的值。双倍的内存。如果你取消设置$str,这将不会发生:

for($i=0;$i<3;$i++) {
    $str = str_repeat("Hello", 10000);
    echo memory_get_peak_usage(), PHP_EOL;
    unset($str);
}

// outputs something like
375904
376016
376016

有影响吗?嗯,引用的文章已经总结得非常好了:

这不是至关重要的,除非出现问题。

当你不再需要变量时,取消设置它们并不会产生负面影响。也许你正在使用共享主机并想对大型数据集进行迭代。如果取消设置可以避免 PHP 引发 Allowed memory size of XXXX bytes exhausted 错误,那么这一微小的努力就值得了。

还应该考虑到的是,即使请求生命周期只有一秒钟,将内存使用量翻倍也会有效地减半可以同时处理的最大请求数量。如果你离服务器的限制很远,那无所谓,但如果你接近限制,那么一个简单的取消设置操作就能为你节省购买更多 RAM 或另外一个服务器的资金。


在当前项目中,我正在使用PHP通过循环生成多个大小不同的HTML页面,因此我应该在每次循环结束时明确取消保存内容的变量。这可能是“关键”的,对吗? - dd0x
在理论上,是的。但在实践中,你应该使用像 XDebug 这样的工具来分析你的应用程序,以确定它是否真正关键。我认为在 PHP 中取消变量的设置更多地是一种扩展优化,而不是绝对必要。 - Gordon
@dd0x 只是补充一下,PHP 有一个垃圾回收器,确保99.9%的时间你不必担心。 - Yacoby
@Yacoby 我已在问题下面链接了垃圾回收页面 ;) 即使启用GC,PHP在上面的示例中仍将使用双倍的内存。 - Gordon
“它并不是很关键,除非它是。”这对于大型项目非常重要,你会遇到这个难题并花费大量时间来解决它。我建议在大变量上使用它。 - Dillon Burnett

9

在许多情况下,unset实际上不会释放太多东西,因此它的使用通常是毫无意义的,除非您的代码逻辑需要它不存在。


3
应该指出的是,在脚本执行结束时,所有内存都会被释放,因此在执行结束之前取消设置将没有什么好处(甚至可能对性能有害)。 - mattbasta

5

使用类似C语言编写的应用程序通常运行数小时。但通常php应用程序的运行时间仅约为0.05秒。因此,使用unset函数并不是非常重要。


6
尽管这可能是真的,但它并不是正确的答案。我已经运行了几天的PHP脚本。由于PHP是垃圾回收的,脚本运行的时间大多数情况下是不相关的。 - Yacoby
2
答案还给人的印象是,在长时间运行的脚本中需要使用unset,而unset相当于free - Yacoby
@Yacoby "我已经运行了几天的 PHP 脚本",也许你需要考虑使用其他针对特定任务的语言。PHP 更适合用于 Web 应用程序,而网页不需要持续运行数天。当然,现在的 Web 服务器更加强大(即使是每月 3 英镑的便宜托管),而且 PHP 垃圾回收有所改善。不建议取消变量以释放资源。 - James

0

这要看情况,你应该确保取消设置非常长的字符串(例如从数据库中选择的博客文章内容)。

<?php
$post = get_blog_post();
echo $post;
unset($post);
?>

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