ガベージ コレクター (GC) は PHP の内部メモリ管理システムですが、理解すべき微妙な点がいくつかあります。
GC はメモリ管理を自動化し、手動タスクでメモリを処理する煩わしさ (面倒な作業) を排除します。
これにより、開発者は「メモリ不足」エラーを過度に心配することなく、ビジネス ロジックに集中できます。
もちろん、それは魔法ではありません。
不要になったオブジェクトを解放すると、メモリ リークが防止されます。
GC はカウント メカニズムを使用して、削除する要素を決定します。特定のオブジェクトを指す参照がない場合 (つまり、$counter = 0)、このオブジェクトはクリーンアップの対象となります。
これは非常にうまく機能しますが、一部の参照には問題がある可能性があります:
class A { public $b; } class B { public $a; } $a = new A(); $b = new B(); $a->b = $b; $b->a = $a; unset($a); unset($b);
この設計が悪い場合、$a と $b の設定を解除しても、PHP はメモリを解放しません。$a と $b は相互に参照しているため、PHP はそれらがまだ使用されていると認識します。
幸いなことに、そのための Cycle Collector と呼ばれる別のメカニズムがあります。
gc_collect_cycles();
大まかに言えば、コレクターはすべての参照を走査し、アルゴリズムを適用して使用中のオブジェクトにマークを付けます。これにより、収集するオブジェクト (マークされていないオブジェクト) が明らかになります。
ただし、PHP は、循環参照の可能性がある 10,000 オブジェクト のしきい値に達するまで、自動循環コレクションをトリガーしません。
繰り返しますが、これは魔法ではないため、gc_collect_cycles() を呼び出す必要があるのはごく一部の場合のみです。
設計が不適切だと、オブジェクト間の関係が複雑になり、参照が増え、ガベージ コレクションが頻繁に発生する可能性があります。
参照カウントされる各オブジェクトには、参照カウント用に追加のストレージが必要です。
出典: Wikipedia - 参照カウント
メモリ クリーンアップ操作に関連するオーバーヘッドは、全体的なパフォーマンスに大きな影響を与え、最終的には特定のシナリオでの実行時間が長くなる可能性があります。
10 年前、Composer は gc_disable() 関数を使用するだけでパフォーマンスが大幅に向上しました。
出典: Composer - GC の無効化
確かに、PHP 7 では GC が大幅に改善されたため、2014 年の状態とは異なります。
さらに、PHP 8 バージョンではメモリ割り当て戦略が改善され、監視を強化するために GC 操作に関する有用な統計が追加されました (8.3 の gc_status())。
ほとんどの PHP アプリケーションはリクエスト駆動型であり、メモリはリクエストの終了時に自動的にクリアされます。
繰り返しますが、これはとてもクールですが、魔法ではありません。非同期リクエストと存続期間の長いオブジェクト/デーモンでは何が起こりますか?
ある時点でメモリ リークが発生する可能性があります。
この時点では、PHP の GC が他の言語とどのように異なるのかがわからないかもしれません。
ほとんどの場合、他の言語はガベージを収集するために参照カウントに依存しないか、異なる実装を使用する可能性があります。
たとえば、多くの場合、未使用のオブジェクトにもマークを付けるトレース アルゴリズムが使用されていますが、段階的には動作しません。それはグラフの走査です。
さらに、一部の言語ではそのような直接制御 (実行時のオン/オフなど) が許可されていません。
いつものように、いくつかの利点と不便があるため、いくつかのハイブリッドなアプローチが見られるかもしれません。
組み込みの gc_* ヘルパーを活用できます。
例:
これらの関数は、必要な場合、ガベージ コレクションのデバッグや微調整に役立ちます。
さらに詳しい情報については、この投稿をお読みください:
PHP 7.4 では弱い参照が導入され、PHP 8 では弱いマップが導入されました。
弱いマップは、弱い参照のコレクションとして説明できます。
このデータ構造は、PHP が乱雑に作成したり過剰なスペースを消費したりすることなく項目を追跡するのに役立つ多用途のキー/値ストアです。
ガベージ コレクションを妨げる可能性のある [強力な] 参照がないため、不要になったときにすぐに消去される一時ストレージとして見ることができます。
class A { public $b; } class B { public $a; } $a = new A(); $b = new B(); $a->b = $b; $b->a = $a; unset($a); unset($b);
ほとんどの用途では、PHP がすでにメモリ管理を処理しているため、メモリ管理について心配する必要はありません。
ただし、最新のスタックでは有効期間の長いオブジェクトが使用されているため、アプリケーションでメモリ リークの可能性がないか監視する必要があります。
問題が発生した場合は、コードを最適化するか、GC を直接操作する必要がある場合があります。
以上がPHP: ガベージコレクターを簡単な言葉で説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。