2009-09-03 97 views
3

我試圖避免PHP中的內存泄漏。當我創建一個對象並最終取消它時,它仍然在內存中。未設置看起來像:PHP內存泄漏和叉

$obj = NULL; 
unset($obj); 

仍然這不會幫助。

我的問題是什麼時候會發生什麼時,我分叉的進程和對象將被創建並在子線程中被破壞?這是否一樣? 或者有沒有其他方式如何釋放內存?

這是將消耗少量內存的導入腳本。

回答

12

PHP 5.3有一個垃圾收集器,可以收集循環引用。這可能是值得一試:

gc_enable(); 

class A { 
    public function __construct() { 
    $this->data = str_repeat("A", 1024000); 
    } 
} 

$mem = memory_get_usage(); 
$a = new A(); 
$mem2 = memory_get_usage(); 
$a->a = $a; 
$a->a->mydata = $a->data . 'test'; 
$mem3 = memory_get_usage(); 
unset($a); 
gc_collect_cycles(); 
$mem4 = memory_get_usage();  

printf("MEM 1 at start %0.2f Mb\n", ($mem/1024)/1024); 
printf("MEM 2 after first instantiation %0.2f Mb\n", ($mem2/1024)/1024); 
printf("MEM 3 after self-ref: %0.2f Mb\n", ($mem3/1024)/1024); 
printf("MEM 4 after unset(\$a): %0.2f Mb\n", ($mem4/1024)/1024);  

輸出:

MEM 1 at start: 0.31 Mb 
MEM 2 after first instantiation: 1.29 Mb 
MEM 3 after self-ref: 2.26 Mb 
MEM 4 after unset($a): 0.31 Mb 
+0

+1,很好的示例數據 – 2009-09-03 09:01:41

5

在調用unset()之前,不需要將變量設置爲NULL。請注意,unset()不會強制釋放內存。您可能希望檢查的主要內容是您的對象清除任何引用必須在您取消設置之前對大量數據進行清除。

1

以及您導入腳本不應該擺在首位使用RAM的一些演出。嘗試將大塊數據存儲在另一個地方(文件系統或數據庫),當你不需要它時。同時考慮一次導入較小的部分,即使需要較長的時間處理,也不是全部都在一個大塊中,但這樣您就可以權衡大內存消耗。

你在說什麼不是內存泄漏,因爲這是一個有記錄的,衆所周知的行爲。正如MathieuK所說,在PHP5.3中,您可能會使用一些gc *函數,但我從未測試過它們。 PHP是一種非常糟糕的語言,用於處理臨時的大塊數據,因爲在分配之後,分配的內存永遠不會再被釋放,即使您未設置它(這是因爲分配的內存會被重用,而這在網頁中是一件好事,但在大型「硬核」腳本中不是好事。)。