2012-12-29 35 views
6

的代码演示了更好的就是我要问:PHP在函数结束后立即释放局部变量吗?

function foo(){ 

    $var = get_huge_amount_of_data(); 

    return $var[0]; 
} 


$s = foo(); 

// is memory freed here for the $var variable created above? 

do_other_stuff(); // need memory here lol 

所以我知道是$ var被在某一点释放,但PHP有效地做到这一点?或者我手动需要取消设置昂贵的变量?

+0

* * *你不能这样问。你认为*有效*可能是不同的(很可能是你提出的BTW风格)在PHP中,实际上***是有效的*。 – hakre

+0

嗯,我的意思是,只要显而易见变量不再被使用,就这样做。 –

+0

更早。随着函数结束,所有本地*变量*都消失了。数据是否暂时存储在内存中并不重要。但要知道你需要更多地了解内存管理,我想这不是你的优势(请不要冒犯)。仅仅因为局部变量不再使用,从系统中立即取消分配内存块就太昂贵了。 – hakre

回答

3

你可以看到在一类这个例子,那是因为你可以“捕获”在课堂上释放一个变量析构函数:

class a { 
    function __destruct(){ 
    echo "destructor<br>"; 
    } 
} 

function b(){ // test function 
    $c=new a(); 
    echo 'exit from function b()<br>'; 
} 

echo "before b()<br>"; 
b(); 
echo "after b()<br>"; 

die(); 

此脚本输出:

before b() 
exit from function b() 
destructor 
after b() 

所以这是现在清楚的是变量在函数出口处被销毁。

+0

但是,这不适用于主要范围。您还可以在主脚本中设置一个对象变量,并查看它何时被销毁 - 即使您之前明确调用它的析构函数,它也会一直保留到“死亡”结束。 – Voitcus

2

是的,这是因为$var是声明在堆栈上,并尽快将其清除超出范围

你可以参考这个https://stackoverflow.com/a/5971224/307157

+1

我在那个链接里什么也看不到,甚至暗示你说的是什么。该页面完全是关于语义的。任何其他参考? -1现在。 – delnan

2

所以我知道是$ var得到在某个时刻释放得到,但PHP有效地做到了吗?或者我手动需要取消设置昂贵的变量?

是的,PHP做得很好。这是一个你永远不需要考虑的问题。在你的情况下,我宁愿考虑$var = ..return ..之间的时刻,因为那时你无法避免内存消耗。您应该尝试找到一种解决方案,您不需要通过get_huge_amount_of_data()获取整个数据集,然后选择一个项目,但只选择所需的数据。

4

是的,它得到释放。

您可以通过使用检查:

function a() { 
    $var = "Hello World"; 
    $content = ""; 
    for ($i = 0; $i < 10000; $i++) { 
     $content .= $var; 
    } 
    print '<br>$content size:'.strlen($content); 
    print '<br>memory in function:'.memory_get_usage(); 
    return null; 
} 

print '<br>memory before function:'.memory_get_usage(); 
a(); 
print '<br>memory after function:'.memory_get_usage(); 

输出:

功能PHP中使用273312个字节
memory before function:273312 
$content size:110000 
memory in function:383520 
memory after function:273352 

之前。
在功能完成之前,我们再次检查了内存使用情况,并使用了383520.
我们检查了$ content的大小,它是110000字节。
273312 + 110000 = 383312
其余的208字节来自其他变量(我们只计算$ content)
函数完成后,我们再次检查内存使用情况并返回(几乎(40字节差异))和以前一样。

40个字节的差异可能是函数声明和for循环声明。

相关问题