2009-09-03 23 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、素敵なサンプルデータ –

5

unset()を呼び出す前に変数をNULLに設定する必要はありません。ただし、unset()はメモリの解放を強制しません。あなたがチェックしたい主な事は、あなたのオブジェクトが参照をクリアすることです。は、それを設定解除する前に大量のデータを持たなければなりません。

1

だけでなく、あなたのインポートスクリプトが最初の場所でラムのいくつかのギグを使用しないでください。大量のデータを別の場所(ファイルシステムやDB)に保存するようにしてください。また、一度に小さなセクションをインポートすることも考えてください。処理時間は長くかかりますが、1つの大きなチャンクではありませんが、この方法では大きなメモリ消費をトレードオフします。

これは文書化された、よく知られている動作であるため、あなたの話はメモリリークではありません。 MathieuKが言っているように、PHP5.3ではいくつかのgc *関数を使うことができますが、テストしたことはありません。一時的な大量のデータを扱うためにPHPを使用するのは非常に難しい言語です。割り当て後、割り当てられたメモリが再利用されるため、割り当てられたメモリは再び解放されません。ウェブページでは良いことだが、大きな「ハードコア」スクリプトではうまくいかない。)。

関連する問題