ホームページ >バックエンド開発 >PHPチュートリアル >PHP レポートをしばらく実行するとメモリ オーバーフローが発生するのはなぜですか?

PHP レポートをしばらく実行するとメモリ オーバーフローが発生するのはなぜですか?

WBOY
WBOYオリジナル
2016-12-01 00:56:491585ブラウズ

データベースから一度に100,000個のデータを読み取り、ループ中にいくつかの計算を実行しましたが、プログラムが実行された後、関連する変数は次のループで上書きされます。一定期間、メモリ オーバーフローが報告されましたが、なぜ最初にメモリ オーバーフローが報告されなかったのですか?私の理解では、演算結果の保存に変数を使用していないため、メモリオーバーフローが発生した場合は最初に報告されるはずです。

返信内容:

データベースから一度に100,000個のデータを読み取り、ループ中にいくつかの計算を実行しましたが、プログラムが実行された後、関連する変数は次のループによって上書きされます。一定期間、メモリ オーバーフローが報告されましたが、なぜ最初にメモリ オーバーフローが報告されなかったのですか?私の理解では、演算結果の保存に変数を使用していないため、メモリオーバーフローが発生した場合は最初に報告されるはずです。

phpバージョン5.5以降

  • ループ内で yield キーワードを使用すると、反復内の中間変数が追加のメモリ領域を占有しません

例:

リーリー

実際、php では、変数は zval 変数を通じて保存されます。zend_uint refcount__gc は、変数の数を保存するためのこの変数のカウンターです。変数が生成されると、その refcount=1 になります。$a = $b などの一般的な代入操作では zval の refcount が 1 ずつ増加し、それに応じて unset 操作によって 1 ずつ減少します。 PHP5.3 より前では、GC の実装に参照カウント メカニズムが使用されていました。zval の refcount が 0 未満の場合、Zend エンジンは zval を指す変数が存在しないと判断し、その結果、zval が占有しているメモリ空間を解放していました。ズヴァル。しかし、物事はそれほど単純ではない場合もあります。 zval を指す変数が設定されていない場合でも、単純な参照カウント メカニズムでは循環参照される zval を GC できず、その結果メモリ リークが発生することが後でわかります。

ループ内で変数を上書きすると、実際の再カウント値が減らないため、占有されていたメモリが解放されず、最終的には必ず爆発します。

解決策:

リーリー

問題分析:

リーリー

考えられる理由:

リーリー

データベースから 100,000 個のデータを読み取ると、メモリ不足になる可能性があります

変数を再代入する際、実際にはメモリ上のオブジェクトデータがCOPYされ、unsetかGCでのみ解放されるような印象がありますが、関連する情報は見つかりませんでした。

PHP は動的言語であり、同じ変数を使用すると、同じメモリ領域を使用するように見えますが、実際はそうではありません。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。