ホームページ > バックエンド開発 > PHPチュートリアル > PHP: ガベージコレクターを簡単な言葉で説明

PHP: ガベージコレクターを簡単な言葉で説明

Linda Hamilton
リリース: 2024-11-29 00:46:11
オリジナル
832 人が閲覧しました

ガベージ コレクター (GC) は PHP の内部メモリ管理システムですが、理解すべき微妙な点がいくつかあります。

? GC はなぜ存在するのでしょうか?

GC はメモリ管理を自動化し、手動タスクでメモリを処理する煩わしさ (面倒な作業) を排除します。

これにより、開発者は「メモリ不足」エラーを過度に心配することなく、ビジネス ロジックに集中できます。

もちろん、それは魔法ではありません。

?要するに 10,000 個のオブジェクト

不要になったオブジェクトを解放すると、メモリ リークが防止されます。

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 はどれくらい違うのですか?

この時点では、PHP の GC が他の言語とどのように異なるのかがわからないかもしれません。

ほとんどの場合、他の言語はガベージを収集するために参照カウントに依存しないか、異なる実装を使用する可能性があります。

たとえば、多くの場合、未使用のオブジェクトにもマークを付けるトレース アルゴリズムが使用されていますが、段階的には動作しません。それはグラフの走査です。

さらに、一部の言語ではそのような直接制御 (実行時のオン/オフなど) が許可されていません。

いつものように、いくつかの利点と不便があるため、いくつかのハイブリッドなアプローチが見られるかもしれません。

?‍? PHP の GC との対話

組み込みの gc_* ヘルパーを活用できます。

例:

  • gc_collect_cycles はガベージ コレクションを手動でトリガーします
  • gc_status() は現在のステータスを返します
  • gc_disable() はそれを無効にします
  • gc_enable() で有効化します

これらの関数は、必要な場合、ガベージ コレクションのデバッグや微調整に役立ちます。

?メモリエラーを理解する

さらに詳しい情報については、この投稿をお読みください:

PHP: The Garbage Collector explained with simple words

PHP: メモリ エラー

spO0q ? ・ '23年5月24日

#php #初心者 #プログラミング

?弱い地図が助けになるでしょうか?

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);
ログイン後にコピー
ログイン後にコピー

✅ 長所

  • 非常に簡単です
  • キャッシュやメモ化 (高価な計算など) に最適

❌ 短所

  • キー (オブジェクト) はガベージ コレクションを防止しませんが、値はガベージ コレクションを防止できるため、「任意の値」という用語は誤解を招く可能性があります (値として単純なデータ型のみを使用します)
  • 貴重な使用例は限られています

?コードを最適化する

  • 相互依存性を減らす設計パターンを活用する
  • 依存性注入を使用する
  • 大きすぎるデータセットをメモリにロードせず、巨大な配列の代わりにコレクションとジェネレーターを使用してください
  • メモリ使用量を監視
  • メトリクスを使用してコードをプロファイリングします
  • gc_enable()、gc_disable()、および gc_collect_cycles() は控えめに使用してください

まとめ

ほとんどの用途では、PHP がすでにメモリ管理を処理しているため、メモリ管理について心配する必要はありません。

ただし、最新のスタックでは有効期間の長いオブジェクトが使用されているため、アプリケーションでメモリ リークの可能性がないか監視する必要があります。

問題が発生した場合は、コードを最適化するか、GC を直接操作する必要がある場合があります。

以上がPHP: ガベージコレクターを簡単な言葉で説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート