ホームページ > バックエンド開発 > PHP7 > php7 ガベージ コレクション メカニズムについてのチャット

php7 ガベージ コレクション メカニズムについてのチャット

coldplay.xixi
リリース: 2023-02-17 18:48:02
転載
2295 人が閲覧しました

PHP7ガベージ コレクションの仕組みを紹介するコラム

php7 ガベージ コレクション メカニズムについてのチャット

推奨 (無料) ): PHP7

記事ディレクトリ

  • Zval構造
  • Circular参照 メモリ リークの原因
  • オブジェクトと配列のリサイクル プロセス
    • ガベージ コレクションの原則
##php GC を理解する際には、php 変数の基礎となる実装を紹介する必要があると思います。

zvalの構造

// php 变量对于的c结构体
struct _zval_struct {
    zend_value value;
    union {
       ……
    } u1;
    union {
        ……
    } u2;
};
ログイン後にコピー
主にガベージコレクションの話なので、u1 u2 Unionの機能を簡単に紹介します


u1 構造は比較的複雑です。主に変数の型を識別するために使用されると思います
u2 ほとんどは補助フィールド、変数の内部関数の実装、キャッシュの利便性の向上などです。 . 次は私たちです 主人公です

zend_value 構造体に埋め込まれた共用体でもあります

typedef union _zend_value {
    zend_long         lval;//整形
    double            dval;//浮点型
    zend_refcounted  *counted;//获取不同类型的gc头部
    zend_string      *str;//string字符串
    zend_array       *arr;//数组
    zend_object      *obj;//对象
    zend_resource    *res;//资源
    zend_reference   *ref;//是否是引用类型
  
    // 忽略下面的结构,与我们讨论无关
    zend_ast_ref     *ast;
    zval             *zv;
    void             *ptr;
    zend_class_entry *ce;
    zend_function    *func;
    struct {
        ZEND_ENDIAN_LOHI(
            uint32_t w1,
            uint32_t w2)
    } ww;
} zend_value;
ログイン後にコピー
参照カウントは

の値に記録されますzvalzend_refcounted *countedこのタイプ、ガベージ コレクション メカニズムもこれに基づいています。

typedef struct _zend_refcounted_h {
    uint32_t         refcount;          /* reference counter 32-bit */
    union {
        struct {
            ZEND_ENDIAN_LOHI_3(
                zend_uchar    type,
                zend_uchar    flags,    /* used for strings & objects */
                uint16_t      gc_info)  /* keeps GC root number (or 0) and color */
        } v;
        uint32_t type_info;
    } u;
} zend_refcounted_h;
ログイン後にコピー
すべての複合型の定義は、

zend_refcounted_h 構造体で始まります。参照カウントに加えて、この構造体には GC 関連の構造体もあります。したがって、GC リサイクルを行う場合、GC は行われません特定の型を気にする必要はありませんが、すべて zend_refcounted* 構造体として処理できます。 #変数の自動リサイクル

PHP では

array を除きますobject 型変数、残りのほとんどは自動的にリサイクルされます。 PHP 通常の変数のリサイクルは、変数への参照の数に関係します。

公式例

$a = 1;
$b = $a;
xdebug_debug_zval('a');
$a =10;
xdebug_debug_zval('a');
unset($a);
xdebug_debug_zval('a');
ログイン後にコピー
結果

a:
(refcount=2, is_ref=0),int 1
a:
(refcount=1, is_ref=0),int 10
a: no such symbol
ログイン後にコピー

$a =10の場合、PHPのCOW(コピーオンライト)メカニズムが関与していることがわかります。 , $b は元の $a をコピーして両者の参照関係を解除しますので、a の参照数(refcount)は 1 になります。

そして、uset($a) を実行すると、a への参照の数は 0 になります。これはガベージ変数とみなされ、スペースが解放されます。

例を挙げてください

$a = [1];
$a[1] = &$a;
unset($a);
ログイン後にコピー
unset($a) 前の $a の型は参照型です

a:
(refcount=2, is_ref=1),
array (size=2)
  0 => (refcount=1, is_ref=0),int 1
  1 => (refcount=2, is_ref=1),
    &array<
ログイン後にコピー

unset($ a) その後、次のようになります。

このとき、

unset を実行すると、refcount が 2 から 1 に変わります。 $a を指す内部参照なので、外部で占有しているスペースは破壊されません。

その後、外部参照が壊れていて使用できません。 C言語でワイルドポインタと呼ばれる「オーファン」となります。 phpでは循環参照といいます。メモリーリーク。変数を破棄したい場合は、php スクリプトが終了するまで待つだけです。

循環参照によるメモリ リーク

このガベージをクリーンアップするために、2 つの基準が導入されます

    参照カウントがゼロに削減されます。変数コンテナはクリア (解放) され、ガベージではありません。
  • zval の参照カウントが削減後も 0 より大きい場合、ガベージ サイクルに入ります。次に、ガベージ サイクル中に、参照カウントが 1 減らされているかどうかを確認し、どの変数コンテナの参照がゼロであるかを確認して、どの部分がガベージであるかを見つけます。
  • #循環参照は基本的に配列とオブジェクトにのみ現れます。オブジェクトはそれ自体が参照であるためです。

オブジェクトと配列のリサイクル プロセス

php7 のガベージ コレクションは 2 つの部分で構成されます。1 つはガベージ コレクターで、もう 1 つはガベージ コレクション アルゴリズムです。

ガベージ コレクターは、ガベージである可能性がある前述の要素をリサイクル プールに収集します。つまり、変数

zend_refcount>0

がリサイクル プールに配置されます。リサイクル プールの値が一定の量に達すると、均一に走査されます。模擬削除を実行します。zend_refcount=0 の場合、ゴミとみなされ、直接削除されます。 リサイクル プール内のすべての変数を走査し、各変数に基づいて各メンバーを走査します。メンバーがまだネストされている場合は、走査を続けます。次に、すべてのメンバーのシミュレートされた refcount を -1 に設定します。このとき外部変数の参照回数が0の場合。そうすれば、それは明らかにゴミとみなされます。 0 より大きい場合、参照の数は復元され、ガベージ コレクション プールから取り出されます。

ガベージ コレクションの原理

変数がガベージではない場合、そのすべてのメンバー変数の参照が 1 つ減らされた後、合計変数の参照が減らされます。絶対に0にはなりません。

言うのはかなり難しいので、例を挙げてみましょう。初めて sf.gg を閲覧したときに GC に関する質問を見つけたので、それに答えました。 GC ガベージ コレクションの仕組みについて

トピックは次のとおりです


//我的回答
1、只要zval.value的refcount减一,然后缺其refcount的值不为0那么它就可能是垃圾,进入垃圾周期。
2、进入垃圾池遍历所有成员,包括其嵌套的成员,都对其做 refcount-1的操作,看外部的引用是否为0。

那么对于 题主的问题来说,
首先,你要想$a为垃圾,一定要先对 unset($a)操作,那么此时 $a的 refcount = 2
对于$a[0] refcount-1 不影响外部的$a,
$a[1] refcount-1 ,此时 $a的 refount=1
$a[2] refcount-1 ,此时 $a 的 refount=0 
模拟减结束,那么此变量被当成垃圾回收。
ログイン後にコピー

更多编程相关知识,请访问:编程教学!!

以上がphp7 ガベージ コレクション メカニズムについてのチャットの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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