在PHP脚本中调用unset()


Calling unset() in PHP script

来自C / C ++背景,我习惯于做自己的垃圾回收-即在使用资源后释放资源(即C ++中的RAII)。

使用它们后,我发现自己未设置(主要是ORM)变量。 这个习惯有什么好处吗?

我记得在某处读过,未设置变量将它们标记为删除,以引起PHP的GC注意-这可以帮助服务器端使用资源-是还是假?

[编辑]

我忘了提一下,我正在使用PHP 5.3,而且我进行的大多数unset()调用都在一个循环中,在该循环中我正在处理多个"大量" ORM变量


我发现,如果您必须大量使用unset,则可能做错了。让范围界定为您做"设置"。考虑两个例子:

1:

1
2
3
4
5
6
7
$var1 = f( ... );
....
unset( $var1 );

$var2 = g( ... );
....
unset( $var2 );

2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function scope1()
{
     $var1 = f( ... );
     ....
} //end of function triggers release of $var1

function scope2()
{
     $var2 = g( ... );
     ....
} //end of function triggers release of $var2

scope1();
scope2();

第二个示例是可取的,因为它可以清楚地定义范围并降低将变量泄漏到全局范围(仅在脚本末尾释放)的风险。

编辑:

要记住的另一件事是,PHP中的unset成本(CPU)比常规作用域垃圾回收高。尽管差异很小,但它表明了PHP团队对unset的重视程度。如果有什么unset应该使PHP能够了解如何释放内存,但实际上会增加执行时间。 unset实际上只是释放不再需要的变量的黑客,除非您做相当复杂的事情,重用变量(对旧变量使用自然的unset)和作用域应该是您所需要的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function noop( $value ){}

function test1()
{
    $value ="something";
    noop( $value ); //make sure $value isn't optimized out
}

function test2()
{
    $value ="something";
    noop( $value ); //make sure $value isn't optimized out
    unset( $value );
}

$start1 = microtime(true);
for( $i = 0; $i < 1000000; $i++ ) test1();
$end1 = microtime(true);

$start2 = microtime(true);
for( $i = 0; $i < 1000000; $i++ ) test2();
$end2 = microtime(true);

echo"test1".($end1 - $start1)."\
"
; //test1 0.404934883118
echo"test2".($end2 - $start2)."\
"
; //test2 0.434437990189

如果在长脚本中的早期使用了非常大的对象,并且对象没有机会超出范围,则unset()可能有助于内存使用。在大多数情况下,对象超出范围,它们会自动标记为GC。


我建议读一读


当遍历和制作数组副本时遇到内存问题时,我不得不使用unset。我会说不要使用它,除非您处于这种情况下,否则GC将自动启动。


PHP GC通常足够好,因此您通常不需要在简单变量上调用unset()。但是,对于对象,GC仅在它们离开作用域时销毁它们,并且没有其他对象引用它们。在这种情况下,取消设置可以帮助记忆。参见http://us3.php.net/manual/en/language.references.unset.php


  • 我认为PHP变量只能在脚本的整个生命周期内保留,因此除非脚本特别长时间运行或一步就使用大量临时内存,否则它不太可能起到很大的作用。
  • 显式清除可能比让它们在启动时自动清除要慢。
  • 您将添加更多的代码,这通常会使事情变慢,除非您知道它会有所帮助。
  • 无论如何,过早的优化。

不去查找一些证据,我要说的是,这并不重要。当您离开函数或脚本结束时,垃圾收集会自动发生。因此,除非您真的被资源所束缚,否则请不要打扰。

好,看了一下这是一个很好的报价:

"Freeing memory - particularly large
amounts - isn't free in terms of
processor time, which means that if
you want your script to execute as
fast as possible at the expense of
RAM, you should avoid garbage
collection on large variables while
it's running, then let PHP do it en
masse at the end of the script."

有关该主题的更多信息,请查看此处第一个答案中提供的链接。


是的,特别是在处理大型数组时,脚本可以运行很多时间。