2

我对几乎在任何地方都使用语言构造感到好奇unset(),在那里我获取了内存或声明了一些变量(无论结构如何)。

我的意思是,当有人声明变量时,它应该什么时候真正留给GC,或者是unset()


示例 1:

<?php
$buffer = array(/* over 1000 elements  */);

// 1) some long code, that uses $buffer

// 2) some long code, that does not use $buffer
?>
  1. 有没有$buffer可能影响第 2 点的表现?
  2. unset($buffer)在进入第 2 点之前我真的需要(或应该)做吗?

示例 2:

<?php
function someFunc(/* some args */){
    $buffer = new VeryLargeObject();

    // 1) some actions with $buffer methods and properties

    // 2) some actions without usage of $buffer

    return $something;
}
?>
  1. 在进入第 2 点之前,我真的需要(或应该)unset($buffer)someFunc()身体内做吗?
  2. GC释放 s 范围内的所有分配的内存(包括引用和对象)someFunc(),何时函数将结束或将找到return语句?

我对技术解释很感兴趣,但也欢迎代码风格的建议。

谢谢。

4

1 回答 1

1

在 php 中,脚本完成后会清理所有内存,并且大多数情况下就足够了。

来自 php.net:

unset() 就像它的名字所说的那样 - 取消设置一个变量。它不会强制立即释放内存。PHP 的垃圾收集器将在它认为合适的时候执行它 - 有意尽快,因为无论如何都不需要这些 CPU 周期,或者直到脚本耗尽内存之前,无论首先发生什么。

如果你正在做 $whatever = null; 那么你正在重写变量的数据。您可能会更快地释放/缩小内存,但它可能会更快地从真正需要它们的代码中窃取 CPU 周期,从而导致更长的整体执行时间。

实际上,您unset()很少会使用它来清理内存,并且在这篇文章中对此进行了很好的描述: https ://stackoverflow.com/a/2617786/1870446

通过unset()对变量执行操作,您将变量标记为“垃圾收集”,因此内存不会立即可用。该变量不再具有数据,但堆栈仍保持较大的大小。
在 PHP >= 5.3.0 中,您可以调用gc_collect_cycles()强制 GC 通过。(先做之后gc_enable())。
但是您必须了解 PHP 是脚本语言,它不是 Java,因此您不应该将其视为一种语言。如果您的脚本真的需要大量的 RAM - 您可以使用 unset 并且当脚本接近超出内存时 - GC 将触发并清理所有无用的内容,包括您未设置的变量。但在大多数情况下,您可以忘记它。
此外,如果您想取消设置您不使用的每个变量 - 不要。它实际上会使您的脚本执行时间更长 - 通过使用更多 CPU 周期 - 以获得在大多数情况下永远不需要的空闲内存。
有些人还说他们使用unset明确表明他们将不再使用变量。我也觉得这是一种不好的做法,对我来说,它只是让所有这些无用的未设置的代码更加冗长。

于 2013-05-15T05:23:51.923 回答