ホームページ >バックエンド開発 >PHPチュートリアル >PHP レポートをしばらく実行するとメモリ オーバーフローが発生するのはなぜですか?
データベースから一度に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 は動的言語であり、同じ変数を使用すると、同じメモリ領域を使用するように見えますが、実際はそうではありません。