この記事では、php7 がガベージ コレクション メカニズムを実装する方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
php GC を理解するとき、php 変数の基礎となる実装を紹介する必要があると感じます。
// 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;
は、参照カウントのタイプ zend_refcounted *zval の値にカウントされます。ガベージ コレクション メカニズムもこれに基づいています。
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 の通常変数のリサイクルは、変数への参照の数に関係します。
$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すると、$aを指す内部参照があるため、refcountが2から1に変わります。外部にある場所 占有された空間は破壊されません。 その後、外部参照が壊れていて使用できません。 C言語でワイルドポインタと呼ばれる「オーファン」となります。 phpでは循環参照といいます。メモリーリーク。変数を破棄したい場合は、php スクリプトが終了するまで待つだけです。 循環参照によるメモリ リークこれらのガベージをクリーンアップするために、2 つのガイドラインが導入されています
オブジェクトと配列のリサイクル プロセス
ガベージ コレクターは、ガベージである可能性がある前述の要素をリサイクル プールに収集します。つまり、zend_refcount>0 の変数がリサイクル プールに配置されます。リサイクル プールの値が一定の量に達すると、均一に走査されます。シミュレートされた削除を実行します。zend_refcount=0 の場合、ゴミとみなされ、直接削除されます。
リサイクル プール内のすべての変数を走査し、各変数に基づいて各メンバーを走査します。メンバーがまだネストされている場合は、走査を続けます。次に、すべてのメンバーのシミュレートされた refcount を -1 に設定します。このとき外部変数の参照回数が0の場合。そうすれば、それは明らかにゴミとみなされます。 0 より大きい場合、参照の数は復元され、ガベージ コレクション プールから取り出されます。
ガベージ コレクションの原則
例
トピックは次のとおりです
//我的回答 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 模拟减结束,那么此变量被当成垃圾回收。推奨学習:php ビデオ チュートリアル
以上がphp7でガベージコレクション機構を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。