来自C / C ++背景,我习惯于自己做垃圾收集 - 即在使用它们之后释放资源(即C ++版本中的RAII)。
在使用它们后,我发现自己未设置(大多数是ORM)变量。这种习惯有什么好处吗?
我记得曾经读过一段时间,那些未设置的变量标志着它们被删除以引起PHP的注意 - 这可以帮助服务器端的资源使用 - 是真还是假?
[编辑]
我忘了提及,我使用的是PHP 5.3,而且我所做的大多数unset()调用都在一个循环中,我正在处理几个'重'ORM变量
答案 0 :(得分:5)
我发现如果您必须unset
使用很多可能做错了。让范围为您做“不安定”。考虑两个例子:
1:
$var1 = f( ... );
....
unset( $var1 );
$var2 = g( ... );
....
unset( $var2 );
2:
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
)并且范围应该都是你曾经需要。
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)."\n"; //test1 0.404934883118
echo "test2 ".($end2 - $start2)."\n"; //test2 0.434437990189
答案 1 :(得分:3)
如果在长脚本的早期使用了一个非常大的对象,并且该对象没有机会超出范围,那么unset()
可能有助于内存使用。在大多数情况下,对象超出范围,并自动标记为GC。
答案 2 :(得分:3)
我建议给this一个阅读
答案 3 :(得分:0)
是的,尤其是在处理大型数组时,脚本需要很长时间才能运行。
答案 4 :(得分:0)
如果不去查一些证据,我会说它并不重要。当您离开函数或脚本结束时,会自动进行垃圾收集。所以除非你真的资源紧张,否则不要打扰。
好的,看了一下。这是一个很好的引用:“释放记忆 - 特别大 金额 - 不是免费的 处理器时间,这意味着如果 你希望你的脚本执行为 尽可能快地牺牲 RAM,你应该避免垃圾 收集大变量的同时 它正在运行,然后让PHP执行它 在剧本结尾处集体。“
有关该主题的更多信息,请查看the first answer here.
中提供的链接答案 5 :(得分:0)
答案 6 :(得分:0)
PHP GC通常足够好,因此您通常不需要在简单变量上调用unset()。但是对于对象,GC只会在它们离开范围时销毁它们,并且没有其他对象引用它们。在这种情况下,Unset可以帮助记忆。见http://us3.php.net/manual/en/language.references.unset.php
答案 7 :(得分:0)
当你在循环并制作数组副本时遇到内存问题时,我不得不使用unset。我会说不要使用它,除非你处于这种情况,因此GC会自动启动。