この記事では、PHP のリサイクル サイクルについて紹介します。これには一定の参考価値があります。困っている友人は参考にしてください。お役に立てれば幸いです。
次の手順は、配列およびオブジェクト型に対してのみ機能します。
伝統的に、PHP で使用される参照カウント メモリ メカニズムは、循環参照メモリ リークを処理できません。ただし、PHP 5.3.0 では、このメモリ リークの問題に対処するために、記事「参照カウント システムにおける同時サイクル コレクション」の同期アルゴリズムを使用しています。
アルゴリズムの完全な説明はこのセクションの範囲をやや超えるため、基本的な部分のみを紹介します。まず、いくつかの基本的なルールを確立する必要があります。参照カウントが増加すると、その参照カウントは引き続き使用され、当然ゴミには入らなくなります。参照カウントがゼロになると、変数コンテナはクリア (解放) されます。つまり、ガベージ サイクルは、参照カウントがゼロ以外の値に減少した場合にのみ発生します。次に、ガベージ サイクル中に、参照カウントが 1 減らされているかどうかを確認し、どの変数コンテナの参照が 0 であるかを確認して、どの部分がガベージであるかを見つけます。
参照カウントが削減される可能性があるすべてのガベージ サイクルをチェックする必要を避けるために、このアルゴリズムはすべての可能なルート (可能なルートは zval 変数コンテナー) をルート バッファーに置きます (ルート バッファー)(紫色でマークされ、ガベージの疑いと呼ばれます)、これにより、考えられる各ガベージ ルート(ガベージ ルートの可能性)がバッファー内に 1 回だけ出現することも保証できます。ガベージ コレクションは、ルート バッファーがいっぱいの場合にのみ、バッファー内のすべての異なる変数コンテナーに対して実行されます。上の画像のステップ A を見てください。
ステップ B では、紫色の各変数の削除をシミュレートします。削除をシミュレーションする際、紫色以外の通常変数の参照回数が「1」減る場合があり、通常変数の参照回数が0になった場合は、再度その通常変数の削除をシミュレーションしてください。各変数はシミュレート削除は 1 回のみ可能で、シミュレート削除後は灰色でマークされます (元の記事では、同じ変数コンテナが 2 回「1」ずつ減らされないようにと書かれていますが、これは間違いです)。
ステップ C では、シミュレーションによって紫色の各変数が復元されます。リカバリは条件付きであり、変数の参照カウントが 0 より大きい場合、シミュレートされたリカバリが実行されます。同様に、各変数は 1 回だけ復元できます。復元後は黒でマークされます。基本的にはステップ B の逆の操作です。このようにして残った回復不能な青いノードの山が削除すべき青いノードとなるので、手順 D でそれらをトラバースして削除します。
アルゴリズムはすべて、シミュレートされた削除、シミュレートされた回復、および実際の削除であり、すべて単純なトラバーサル (最も一般的な深層検索トラバーサル) を使用します。複雑さは、紫色のガベージ変数と疑われる変数だけでなく、シミュレーション操作を実行するノードの数と正の関係があります。
このアルゴリズムの基本を理解したところで、戻ってこれがどのように PHP と統合されるかを見てみましょう。デフォルトでは、PHP のガベージ コレクション メカニズムはオンになっており、それを変更できる php.ini 設定 (zend.enable_gc) があります。
ガベージ コレクション メカニズムがオンになっている場合、ルート バッファーがいっぱいになるたびに、上記のループ検索アルゴリズムが実行されます。ルート キャッシュ領域は固定サイズで、10,000 個の可能なルートを保存できます。もちろん、PHP ソース ファイル Zend/zend_gc.c 内の定数 GC_ROOT_BUFFER_MAX_ENTRIES を変更し、PHP を再コンパイルすることで、この 10,000 の値を変更できます。ガベージ コレクションがオフになっている場合、ループ検索アルゴリズムは実行されませんが、構成でガベージ コレクションがアクティブになっているかどうかに関係なく、ルートが常にルート バッファーに存在する可能性があります。
ガベージ コレクション メカニズムがオフになっている場合、ルート バッファーがルート候補でいっぱいであれば、それ以上のルート候補は明らかに記録されません。記録されていないルートの可能性は、このアルゴリズムでは分析および処理されません。それらが循環参照サイクルの一部である場合、それらは決してクリアされず、メモリ リークの原因となります。
ガベージ コレクションが使用できない場合でもルート候補が記録される理由は、ルート候補を記録する方が、ルート候補が見つかるたびにガベージ コレクションがオンになっているかどうかを確認するよりも高速であるためです。ただし、ガベージ コレクションと分析のメカニズム自体には多くの時間がかかります。
設定 zend.enable_gc を変更することに加えて、gc_enable() 関数と gc_disable() 関数をそれぞれ呼び出してガベージ コレクション メカニズムをオンまたはオフにすることもできます。これらの関数を呼び出すと、構成項目を変更してガベージ コレクション メカニズムをオンまたはオフにするのと同じ効果があります。ルート バッファーがいっぱいでない場合でも、定期的な収集を強制する機能。この目的のために、 gc_collect_cycles() 関数を呼び出すことができます。この関数は、このアルゴリズムを使用してリサイクルされたサイクル数を返します。
ガベージ コレクションのオンとオフを切り替えたり、自律的な初期化を許可したりする理由は、アプリケーションの一部が時間に依存する可能性があるためです。この場合、おそらくガベージ コレクションを使用したくないでしょう。もちろん、アプリケーションの特定の部分のガベージ コレクションをオフにすると、限られたルート バッファーに収まらないルートが存在する可能性があるため、メモリ リークが発生する可能性があります。したがって、gc_disable() 関数を呼び出してメモリを解放する直前に、最初に gc_collect_cycles() 関数を呼び出すことが賢明です。これにより、ルート バッファーに格納されているすべての可能なルートがクリアされるため、ガベージ コレクション メカニズムがオフになったときに、空のバッファーを残して、ルート バッファーに格納できるスペースを増やすことができます。
以上がPHPリサイクルサイクルの紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。