2013-12-19 84 views
1

我想了解unset()如何處理類和它們的屬性。我寫了一個測試來查看內存使用情況。類別的PHP內存使用情況

class B {} 
class A { 
    private $b; 
    public function __construct() { 
     $this->b = new B; 
    } 
    public function __destruct() { 
     unset($this->b); 
    } 
} 

echo memory_get_usage() . '<br/>'; 

$a = []; 
for ($i = 0; $i < 5000; $i++) { 
    $a[$i] = new A; 
} 

echo memory_get_usage() . '<br/>'; 

for ($i = 0; $i < 5000; $i++) { 
    $a[$i]->__destruct(); 
    unset($a[$i]); 
} 
unset($a); 

echo memory_get_usage() . '<br/>'; 

我期待的是最後一次的內存使用應該與第一次相似。但它更高:

236184 (before) 
2845320 (peak) 
1219432 (after) 

我真的不明白這是如何工作的。謝謝你的幫助!

注:我試圖使用__destruct(我們從不知道)的其他名稱,但不會改變任何東西。

以下是一些評論,我試着用memory_get_usage(true);結果是這樣的:

262144 (before) 
3145728 (peak) 
2359296 (after) 
+2

PHP的內存使用情況不像這樣確定性。 –

+2

PHP *偶爾會運行垃圾回收,這裏的關鍵字偶爾會*。並非所有未使用的內存都會立即釋放。 – deceze

+2

查看[memory_get_usage()](http://www.php.net/function.memory-get-usage)的描述,然後查看使用'real_usage'參數 –

回答

2

在PHP unset()做它的名字所說的 - 取消設置變量。它不強制立即釋放內存。 PHP的垃圾回收器會在它很快看到適合的意圖時執行它,因爲無論如何這些CPU週期是不需要的,或者是在腳本內存耗盡之前,無論先發生什麼都不需要。

如果你正在做$ whatever = null;那麼你正在重寫變量的數據。您可能會更快地釋放/收縮內存,但它可能會更快地從真正需要它們的代碼中竊取CPU週期,從而導致更長的總體執行時間。

請注意,在php5.3之前,如果在循環引用中有兩個對象,例如在父子關係中,調用父對象的unset()將不會釋放用於父子引用的內存目的。 (當父對象被垃圾收集時,內存也不會被釋放。)bug 33595