「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > PHP: ガベージコレクターを簡単な言葉で説明

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

2024 年 12 月 11 日に公開
ブラウズ:390

ガベージ コレクター (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();

大まかに言えば、コレクターはすべての参照を走査し、アルゴリズムを適用して使用中のオブジェクトにマークを付けます。これにより、収集するオブジェクト (マークされていないオブジェクト) が明らかになります。

ただし、循環参照の可能性がある 10,000 オブジェクトのしきい値に達するまで、PHP は自動循環収集をトリガーしません。

繰り返しますが、これは魔法ではないため、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 が項目を追跡するのに役立つ多用途のキーと値のストアです。

ガベージ コレクションを妨げる可能性のある [強力な] 参照がないため、不要になったらすぐに消去される一時ストレージとして見ることができます:

$object = new stdClass;
$map = new WeakMap();
$map[$object] = true;
$object->name = 'some name';
print_r($map);// $object is stored in $map

unset($object);

print_r($map);// $object is cleaned and no longer available

✅ 長所

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

❌ 短所

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

?コードを最適化する

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

まとめ

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

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

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

リリースステートメント この記事は次の場所に転載されています: https://dev.to/spo0q/php-the-garbage-collector-explained-with-simple-words-1b7d?1 侵害がある場合は、削除するために[email protected]に連絡してください。それ
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3