web-dev-qa-db-ja.com

PHPの「メモリ不足」の問題をどのようにデバッグしますか?

最近、PHPメモリ制限に関していくつかの問題が発生しました:

メモリ不足(22544384が割り当てられました)(232バイトを割り当てようとしました)

問題の原因について多くの情報が残されていないため、これらはデバッグするのが非常に面倒です。

シャットダウン機能を追加すると、

register_shutdown_function('shutdown');

次に、 error_get_last ();を使用します。最後のエラー、この場合は行番号やphpファイル名などの「メモリ不足」の致命的なエラーに関する情報を取得できます。

これは素晴らしいことですが、私のphpプログラムは非常にオブジェクト指向です。スタックの奥深くにあるエラーは、エラーの瞬間の制御構造や実行スタックについてはあまり教えてくれません。 debug_backtrace()、 を試しましたが、エラー時のスタックではなく、シャットダウン中のスタックが表示されます。

Ini_setを使用するか、php.iniを変更するだけでメモリ制限を引き上げることができますが、それでは、実際に多くのメモリを消費しているものや、エラー時の実行フローがどのように見えるかを理解することはできません。

高度なオブジェクト指向PHPプログラムでメモリエラーをデバッグするための優れた方法論を持っている人はいますか?

29
Kevin Owocki
echo '<pre>';
$vars = get_defined_vars();
foreach($vars as $name=>$var)
{
    echo '<strong>' . $name . '</strong>: ' . strlen(serialize($var)) . '<br />';
}
exit();

/* ... Code that triggers memory error ... */

これを使用して、コードの問題セクションの直前に現在割り当てられている変数のリストと、変数のサイズの(非常に)大まかな見積もりを出力します。私は戻って、興味のあるポイント以降で必要のないものをunsetします。

拡張機能をインストールするオプションがない場合に便利です。

上記のコードを変更して、memory_get_usageを使用するように変更すると、変数内のメモリの推定値が異なりますが、それが良いか悪いかはわかりません。

11

Memprof は、特にオブジェクト指向コードで、これらのメモリイータースニペットを見つけるのに役立つphp拡張機能です。

この適応チュートリアル は非常に便利です。

注:この拡張機能をWindows用にコンパイルしようとして失敗しました。そうする場合は、PHPがスレッドセーフでないことを確認してください。いくつかの頭痛の種を避けるために、* nix環境で使用することをお勧めします。

もう1つの興味深いリンクは、phpがメモリを処理する方法を説明する slideshare でした。スクリプトのメモリ使用量に関する手がかりが得られます。

おそらく、方法論に関するあなたの考えはここに欠陥があるのだろうか。

あなたの質問に対する基本的な答え-このエラーが発生している場所を見つけるにはどうすればよいですか? -すでに回答済みです。あなたはそれを引き起こしているものを知っています。

ただし、これは、トリガーエラーが実際には問題ではない場合の1つです。確かに、232バイトのオブジェクトはまったく問題ではありません。その前に割り当てられたのは20+メガです。

それを追跡するのに役立ついくつかのアイデアが投稿されています。ここでは、個々の機能だけでなく、アプリケーションアーキテクチャを「より高いレベル」で見る必要があります。

アプリケーションは、ユーザーの負荷に応じて、アプリケーションが実行するためにより多くのメモリを必要とする可能性があります。または、不要な実際のメモリの占有がいくつかある可能性があります-しかし、あなたは知っているその質問に答えるために何が必要かどうかを知る必要があります。

これは基本的に、探しているものが見つかるまで、必要に応じて行ごと、オブジェクトごと、プロファイリングを行うことを意味します。ビッグメモリユーザー。大きなアイテムが1つか2つないかもしれないことに注意してください...それがとても簡単だったなら!メモリホッグを見つけたら、それらを最適化できるかどうかを判断する必要があります。そうでない場合は、より多くのメモリが必要です。

6
Andrew Barber

関数のドキュメントを確認してください memory_get_usage() 実行時のメモリ使用量を確認してください。

3
fvox

xdebug を使用して、メモリ使用量をプロファイルします。

0
brian_d