PHP7ガベージ コレクションの仕組みを紹介するコラム
推奨 (無料) ): PHP7
記事ディレクトリ
zvalの構造
// php 变量对于的c结构体 struct _zval_struct { zend_value value; union { …… } u1; union { …… } u2; };
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* 構造体として処理できます。
#変数の自動リサイクル
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 になります。
$a = [1]; $a[1] = &$a; unset($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 を実行すると、refcount が 2 から 1 に変わります。 $a を指す内部参照なので、外部で占有しているスペースは破壊されません。
循環参照によるメモリ リーク
このガベージをクリーンアップするために、2 つの基準が導入されます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 サイトの他の関連記事を参照してください。