Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPのガベージコレクションを深掘りしよう

 PHPのガベージコレクションを深掘りしよう

PHPer Kaigi 2025 day2 LT
https://fortee.jp/phperkaigi-2025/speaker/proposal/view/b971cae5-06fc-499c-83f9-b66dad8e878c

ご指摘がありましたがPHP7系からis_refは型定義から削除されており、type内のIS_REFERENCEになっております。
https://hnw.hatenablog.com/entry/20141207

ご指摘いただきありがとうございます。

Rinchoku

March 23, 2025
Tweet

More Decks by Rinchoku

Other Decks in Programming

Transcript

  1. 最初に PHPで開発をしていてメモリ関連で下記経験したことあります か? • PHP Fatal error: Allowed memory size

    of ******bytes exhausted (tried to allocate XXXXbytes) ◦ memory_get_usage(true)でメモリ使用量を見たり
  2. 最初に PHPで開発をしていてメモリ関連で下記経験したことあります か? • PHP Fatal error: Allowed memory size

    of ******bytes exhausted (tried to allocate XXXXbytes) ◦ memory_get_usage(true)でメモリ使用量を見たり • 古いPHPバージョン環境で謎のunset
  3. PHPのガベージコレクションについて • PHP5.3(2009年6月30日)から追加された機能 ◦ 循環参照のバグなどはあったものの • PHPはReference Counting(参照カウント )を採用 ◦

    深さ優先探索を利用 ◦ Concurrent Cycle Collection in Reference Counted Systemsを 採用 • ガベージコレクションのロジックは下記に記載 ◦ php-src/Zend/zend_gc.c ◦ php-src/Zend/zend_gc.h • 参照カウントやフラグの管理は php-src/Zend/zend_types.h
  4. Reference Countingとは • PHPの変数(zval)は下記4つの情報を持つ ◦ 型 ◦ 値 ◦ is_ref

    ▪ 「参照集合」の一部かどうかを示すブール値 ◦ refcount ▪ 1つの zval コンテナをどれだけ多くの 変数名が指すか ▪ 「変数名」を「シンボル」とも呼ばれる • 各スコープ単位にシンボルテーブルが 1つ作られ、変数名はこの シンボルテーブルに保管される
  5. Reference Countingとは • ガベージコレクションが動く条件 ◦ refcountが減少した時 ▪ refcountが0であれば解放 が可能 ▪

    refcountが減少した時はゴミ候補 入り • 詳しくは「ガベージコレクション > 循環の収集」を参照 ◦ root_bufferが保有する値が一定値を超える
  6. Reference Countingとは • 内部的に色でRoot Zvalの状態を管理 している ◦ BLACK:ベース。使用中か解放可能かは不明 ◦ GREY:探査をして、refcountを1減少させたもの

    ◦ WHITE:探査をした結果、解放できる ◦ PURPLE:GC対象のRoot Zval ▪ 変更のたびに各zvalを確認するのを防ぐ目的 • 他にもGREEN、RED、ORANGEがあるが、PHPでは利用していな い
  7. PHPのガベージコレクションの動き 1. Root ZvalからGrayにマークをつける ◦ GrayではなかったzvalをStackしておく ◦ refcountを-1する 2. Root

    Zvalを探査する ◦ GrayのRoot Zvalに対して i. refcountが正→Blackに変更 ii. GrayのzvalをWhiteに変更 3. Whiteにマークされたものを収集し、解放 ◦ 収集時、White-> Blackに変更
  8. PHPのガベージコレクションの動き 1. Root ZvalからGrayにマークをつける ◦ GrayではなかったzvalをStackしておく ◦ refcountを-1する 2. Root

    Zvalを探査する ◦ GrayのRoot Zvalに対して i. refcountが正→Blackに変更 ii. GrayのzvalをWhiteに変更 3. Whiteにマークされたものを収集し、解放 ◦ 収集時、White-> Blackに変更
  9. PHPのガベージコレクションの動き 1. Root ZvalからGrayにマークをつける ◦ GrayではなかったzvalをStackしておく ◦ refcountを-1する 2. Root

    Zvalを探査する ◦ GrayのRoot Zvalに対して i. refcountが正→Blackに変更 ii. GrayのzvalをWhiteに変更 3. Whiteにマークされたものを収集し、解放 ◦ 収集時、White-> Blackに変更 削除のシミュレーション 循環参照により、未使用変数を見つけ る布石
  10. PHPのガベージコレクションの動き 1. Root ZvalからGrayにマークをつける ◦ GrayではなかったzvalをStackしておく ◦ refcountを-1する 2. Root

    Zvalを探査する ◦ GrayのRoot Zvalに対して i. refcountが正→Blackに変更 ii. GrayのzvalをWhiteに変更 3. Whiteにマークされたものを収集し、解放 ◦ 収集時、White-> Blackに変更 循環参照を考慮して無限ループを回避 変更前に削除対象として収集済み
  11. 自己紹介 • 氏名:Rinchoku (リンチョク) • 所属:eForce株式会社(近々…) • X:@stupid_owl • コミュニティ

    ◦ SRE NEXT 2025 コアスタッフ ◦ SRE Kaigi 2025 コアスタッフ • 趣味 ◦ ハンドメイド ◦ 宝石鑑賞
  12. 参考 • https://github.com/php/php-src • https://www.php.net/manual/ja/features.gc.php • https://qiita.com/hinako_n/items/8a7b366a3fe09f43dce8 • https://www.php.net/manual/ja/features.gc.performance-considerations.php •

    https://qiita.com/genie-oh/items/e6dfc49fb9899f931271 • https://fortee.jp/phpcon-2022/proposal/1addf51d-6f72-4c96-9337-034ec6c c0643 • https://qiita.com/pseudo_foxkeh/items/a15e4a5fd6ba679d4841 • https://ja.wikipedia.org/wiki/%E3%82%AC%E3%83%99%E3%83%BC%E3%8 2%B8%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3 %83%B3