2012-03-16 12 views
0

は、私はのようなエラーが出ますので、時々壊すのスクリプトを持っている:memory_get_usage()から取得した値を「ドリルダウン」することはできますか?

PHP Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes) in ... 

メモリの制限が低すぎると128Mで入れなかったです。 (それ以上で十分です)

問題は、スクリプトが進むにつれて、より多くのメモリが必要になることです。基本的には、ループはforです。私はすべての変数をチェックしましたが、スクリプトが成長する「何か」(たとえば配列)を埋めてスクリプトがより多くのメモリを必要とする理由を説明する場所はありません。

私はmemory_get_usage()を使用してメモリの問題を確認しました。私は各反復の後にメモリのフットプリントを印刷して、その数は常に高くなっています。

Xdebugを使用しても、この時点で私を助ける兆候はありません。

ドリルダウンできる方法はありますか、ループするたびにさらに多くのメモリが必要ですか?あなたはその状況をデバッグするために何を提案しますか?

+1

残念ながら、PHPのメモリリークを簡単にデバッグする方法はありません。ループの内容を別のメソッドまたは関数に入れてみてください。だからあなたのループ本体は、その関数呼び出し以外何もありません。 IIRC PHPのガベージコレクタは、関数やメソッドの最後に呼び出されます。あなたが持っているものはすべてループなので、GCは呼び出されません。 –

+0

マイク、私はあなたの提案を試みて、それを呼び出すのではなく関数を呼び出すことがメモリに影響を与えることを発見しました。だから私は "問題"がその機能にあることを知っている。つまり、関数にコードを入れて、すべての変数に 'unset(...)'を実行しても、関数を呼び出すたびにメモリはスクリプトを強制終了するまで高くなります。 GCはそれに影響を与えないようです。 – Maxime

+0

Dohは、簡単な解決策を望んでいました。チェックアウトの私の同様の質問..いくつかの答えが役立つかもしれないhttp://stackoverflow.com/questions/849549/finding-cause-of-memory-leaks-in-large-php-stacks –

答えて

0

短い答えは、ドリルダウンできません。つまり、問題の原因を見つけたのは、サブ関数内のループ内のコードを分割したことです。そして、私は何もせずにループのフットプリントが何であるかだけを確認するように彼ら全員にコメントしました。それから、問題のあるものを見つけるまで関数ごとに関数のコメントを外しました。

問題のある関数を見つけたら、同じプロセスをもう一度やりました。問題のあるコードが見つかるまでコメントをすべてコメントしてからコメントを外してください。

最後に、私はPHPからcreate_functionを使用した関数を呼び出していました。多くの人々がこの機能から「メモリリーク」について「不平を言う」。問題はメモリリークではなく、ループ内でcreate_functionを呼び出すと実際にループする回数だけ多くの関数が作成されるという事実です。これを避けるために、私はこのコンセプトが何千回も機能を再現するのを避けるために見つけました。

<?php 
global $my_func; 
if (!isset($my_func)) { 
    $my_func = create_function($args, $code); 
} 

$my_func(); 
?> 

機能が一度作成されたことを確認するコードを変更すると、問題が解決しました。スクリプト全体では、128MBを超えて壊した後ではなく、8MBのメモリしか使用できません。

関連する問題